@necrolab/dashboard 0.4.61 → 0.4.208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/.prettierrc +1 -27
  2. package/.vscode/extensions.json +1 -1
  3. package/README.md +79 -43
  4. package/backend/api.js +48 -40
  5. package/backend/auth.js +3 -3
  6. package/backend/batching.js +1 -1
  7. package/backend/endpoints.js +77 -13
  8. package/backend/index.js +2 -2
  9. package/backend/mock-data.js +38 -29
  10. package/backend/mock-src/classes/logger.js +8 -8
  11. package/backend/mock-src/classes/utils.js +3 -7
  12. package/backend/mock-src/database.js +0 -0
  13. package/backend/mock-src/ticketmaster.js +79 -79
  14. package/backend/validator.js +2 -2
  15. package/config/configs.json +3 -2
  16. package/config/filter.json +3 -2
  17. package/index.html +10 -81
  18. package/index.js +1 -1
  19. package/package.json +25 -40
  20. package/postcss.config.js +1 -1
  21. package/postinstall.js +17 -98
  22. package/public/android-chrome-192x192.png +0 -0
  23. package/public/android-chrome-512x512.png +0 -0
  24. package/public/apple-touch-icon.png +0 -0
  25. package/public/favicon-16x16.png +0 -0
  26. package/public/favicon-32x32.png +0 -0
  27. package/public/favicon.ico +0 -0
  28. package/public/manifest.json +7 -12
  29. package/public/sw.js +2 -0
  30. package/public/workbox-49fdaf31.js +2 -0
  31. package/public/workbox-49fdaf31.js.map +1 -0
  32. package/public/workbox-88575b92.js +2 -0
  33. package/public/workbox-88575b92.js.map +1 -0
  34. package/public/workbox-a67a7b11.js +2 -0
  35. package/public/workbox-a67a7b11.js.map +1 -0
  36. package/public/workbox-d4314735.js +2 -0
  37. package/public/workbox-d4314735.js.map +1 -0
  38. package/public/workbox-e0f89ef3.js +2 -0
  39. package/public/workbox-e0f89ef3.js.map +1 -0
  40. package/run +9 -176
  41. package/src/App.vue +85 -498
  42. package/src/assets/css/_input.scss +99 -144
  43. package/src/assets/css/main.scss +99 -450
  44. package/src/assets/img/background.svg +2 -2
  45. package/src/assets/img/logo_icon.png +0 -0
  46. package/src/components/Auth/LoginForm.vue +11 -62
  47. package/src/components/Editors/Account/Account.vue +40 -116
  48. package/src/components/Editors/Account/AccountCreator.vue +39 -88
  49. package/src/components/Editors/Account/AccountView.vue +34 -102
  50. package/src/components/Editors/Account/CreateAccount.vue +32 -80
  51. package/src/components/Editors/Profile/CreateProfile.vue +83 -269
  52. package/src/components/Editors/Profile/Profile.vue +47 -132
  53. package/src/components/Editors/Profile/ProfileCountryChooser.vue +20 -82
  54. package/src/components/Editors/Profile/ProfileView.vue +34 -91
  55. package/src/components/Editors/TagLabel.vue +6 -67
  56. package/src/components/Filter/Filter.vue +72 -289
  57. package/src/components/Filter/FilterPreview.vue +30 -171
  58. package/src/components/Filter/PriceSortToggle.vue +4 -74
  59. package/src/components/Table/Header.vue +1 -1
  60. package/src/components/Table/Row.vue +1 -1
  61. package/src/components/Table/Table.vue +2 -19
  62. package/src/components/Tasks/CheckStock.vue +13 -28
  63. package/src/components/Tasks/Controls/DesktopControls.vue +17 -17
  64. package/src/components/Tasks/Controls/MobileControls.vue +45 -8
  65. package/src/components/Tasks/CreateTaskAXS.vue +73 -79
  66. package/src/components/Tasks/CreateTaskTM.vue +142 -94
  67. package/src/components/Tasks/MassEdit.vue +7 -9
  68. package/src/components/Tasks/QuickSettings.vue +55 -169
  69. package/src/components/Tasks/ScrapeVenue.vue +4 -7
  70. package/src/components/Tasks/Stats.vue +23 -52
  71. package/src/components/Tasks/Task.vue +136 -378
  72. package/src/components/Tasks/TaskView.vue +47 -107
  73. package/src/components/Tasks/Utilities.vue +6 -5
  74. package/src/components/icons/Bag.vue +1 -1
  75. package/src/components/icons/Loyalty.vue +1 -1
  76. package/src/components/icons/Mail.vue +2 -2
  77. package/src/components/icons/Play.vue +2 -2
  78. package/src/components/icons/Reload.vue +5 -4
  79. package/src/components/icons/Sandclock.vue +2 -2
  80. package/src/components/icons/Stadium.vue +1 -1
  81. package/src/components/icons/index.js +1 -24
  82. package/src/components/ui/Modal.vue +13 -105
  83. package/src/components/ui/Navbar.vue +38 -171
  84. package/src/components/ui/ReconnectIndicator.vue +55 -351
  85. package/src/components/ui/Splash.vue +35 -5
  86. package/src/components/ui/controls/CountryChooser.vue +62 -200
  87. package/src/components/ui/controls/atomic/Checkbox.vue +10 -119
  88. package/src/components/ui/controls/atomic/Dropdown.vue +39 -208
  89. package/src/components/ui/controls/atomic/MultiDropdown.vue +37 -300
  90. package/src/libs/Filter.js +170 -200
  91. package/src/registerServiceWorker.js +1 -1
  92. package/src/stores/connection.js +53 -51
  93. package/src/stores/logger.js +3 -11
  94. package/src/stores/sampleData.js +235 -207
  95. package/src/stores/ui.js +44 -112
  96. package/src/stores/utils.js +6 -90
  97. package/src/views/Accounts.vue +35 -44
  98. package/src/views/Console.vue +90 -341
  99. package/src/views/Editor.vue +123 -1176
  100. package/src/views/FilterBuilder.vue +251 -607
  101. package/src/views/Login.vue +14 -76
  102. package/src/views/Profiles.vue +25 -44
  103. package/src/views/Tasks.vue +100 -187
  104. package/static/offline.html +50 -192
  105. package/tailwind.config.js +26 -104
  106. package/vite.config.js +16 -73
  107. package/vue.config.js +32 -0
  108. package/workbox-config.js +11 -0
  109. package/artwork/image.png +0 -0
  110. package/dev-server.js +0 -136
  111. package/exit +0 -209
  112. package/jsconfig.json +0 -16
  113. package/src/assets/css/_utilities.scss +0 -388
  114. package/src/assets/img/background.svg.backup +0 -11
  115. package/src/components/icons/Check.vue +0 -5
  116. package/src/components/icons/Close.vue +0 -21
  117. package/src/components/icons/CloseX.vue +0 -5
  118. package/src/components/icons/Key.vue +0 -21
  119. package/src/components/icons/Pencil.vue +0 -21
  120. package/src/components/icons/Profile.vue +0 -18
  121. package/src/components/icons/Sell.vue +0 -21
  122. package/src/components/icons/Spinner.vue +0 -42
  123. package/src/components/icons/SquareCheck.vue +0 -18
  124. package/src/components/icons/SquareUncheck.vue +0 -18
  125. package/src/components/icons/Wildcard.vue +0 -18
  126. package/src/components/ui/controls/atomic/LoadingButton.vue +0 -45
  127. package/src/composables/useClickOutside.js +0 -21
  128. package/src/composables/useDropdownPosition.js +0 -174
  129. package/src/types/index.js +0 -41
  130. package/src/utils/debug.js +0 -1
  131. package/switch-branch.sh +0 -41
  132. package/workbox-config.cjs +0 -63
  133. /package/src/assets/img/{logo_icon-old.png → logo_icon_2.png} +0 -0
@@ -1,42 +0,0 @@
1
- <template>
2
- <svg class="spinner" viewBox="0 0 50 50">
3
- <circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
4
- </svg>
5
- </template>
6
-
7
- <style lang="scss" scoped>
8
- .spinner {
9
- @apply mx-auto;
10
- animation: rotate 2s linear infinite;
11
- z-index: 2;
12
- width: 30px;
13
- height: 30px;
14
-
15
- & .path {
16
- stroke: rgba(70, 198, 210, 100%);
17
- stroke-linecap: round;
18
- animation: dash 1.5s ease-in-out infinite;
19
- }
20
- }
21
-
22
- @keyframes rotate {
23
- 100% {
24
- transform: rotate(360deg);
25
- }
26
- }
27
-
28
- @keyframes dash {
29
- 0% {
30
- stroke-dasharray: 1, 150;
31
- stroke-dashoffset: 0;
32
- }
33
- 50% {
34
- stroke-dasharray: 90, 150;
35
- stroke-dashoffset: -35;
36
- }
37
- 100% {
38
- stroke-dasharray: 90, 150;
39
- stroke-dashoffset: -124;
40
- }
41
- }
42
- </style>
@@ -1,18 +0,0 @@
1
- <template>
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- viewBox="0 0 448 512"
5
- class="square-check-icon"
6
- >
7
- <path
8
- fill="currentColor"
9
- d="M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"
10
- />
11
- </svg>
12
- </template>
13
-
14
- <style scoped>
15
- .square-check-icon {
16
- @apply w-4 h-4;
17
- }
18
- </style>
@@ -1,18 +0,0 @@
1
- <template>
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- viewBox="0 0 448 512"
5
- class="square-uncheck-icon"
6
- >
7
- <path
8
- fill="currentColor"
9
- d="M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM152 232H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24z"
10
- />
11
- </svg>
12
- </template>
13
-
14
- <style scoped>
15
- .square-uncheck-icon {
16
- @apply w-4 h-4;
17
- }
18
- </style>
@@ -1,18 +0,0 @@
1
- <template>
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- viewBox="0 0 512 512"
5
- class="wildcard-icon"
6
- >
7
- <path
8
- fill="currentColor"
9
- d="M208 32c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V172.9l122-70.4c15.3-8.8 34.9-3.6 43.7 11.7l16 27.7c8.8 15.3 3.6 34.9-11.7 43.7L352 256l122 70.4c15.3 8.8 20.5 28.4 11.7 43.7l-16 27.7c-8.8 15.3-28.4 20.6-43.7 11.7L304 339.1V480c0 17.7-14.3 32-32 32H240c-17.7 0-32-14.3-32-32V339.1L86 409.6c-15.3 8.8-34.9 3.6-43.7-11.7l-16-27.7c-8.8-15.3-3.6-34.9 11.7-43.7L160 256 38 185.6c-15.3-8.8-20.5-28.4-11.7-43.7l16-27.7C51.1 98.8 70.7 93.6 86 102.4l122 70.4V32z"
10
- />
11
- </svg>
12
- </template>
13
-
14
- <style scoped>
15
- .wildcard-icon {
16
- @apply w-4 h-4;
17
- }
18
- </style>
@@ -1,45 +0,0 @@
1
- <template>
2
- <button
3
- :class="[
4
- 'btn-primary',
5
- {
6
- 'opacity-50 cursor-not-allowed': loading || disabled,
7
- 'btn-secondary': variant === 'secondary',
8
- 'btn-danger': variant === 'danger'
9
- }
10
- ]"
11
- :disabled="loading || disabled"
12
- @click="$emit('click')"
13
- v-bind="$attrs"
14
- >
15
- <div v-if="loading" class="flex-center gap-2">
16
- <div class="loading-spinner"></div>
17
- <span v-if="loadingText">{{ loadingText }}</span>
18
- </div>
19
- <slot v-else />
20
- </button>
21
- </template>
22
-
23
- <script setup>
24
- defineProps({
25
- loading: {
26
- type: Boolean,
27
- default: false
28
- },
29
- disabled: {
30
- type: Boolean,
31
- default: false
32
- },
33
- loadingText: {
34
- type: String,
35
- default: ''
36
- },
37
- variant: {
38
- type: String,
39
- default: 'primary',
40
- validator: (value) => ['primary', 'secondary', 'danger'].includes(value)
41
- }
42
- });
43
-
44
- defineEmits(['click']);
45
- </script>
@@ -1,21 +0,0 @@
1
- import { onMounted, onUnmounted } from "vue";
2
-
3
- export function useClickOutside(elementRef, callback) {
4
- const handleClickOutside = (event) => {
5
- if (elementRef.value && !elementRef.value.contains(event.target)) {
6
- callback();
7
- }
8
- };
9
-
10
- onMounted(() => {
11
- document.addEventListener("click", handleClickOutside);
12
- });
13
-
14
- onUnmounted(() => {
15
- document.removeEventListener("click", handleClickOutside);
16
- });
17
-
18
- return {
19
- handleClickOutside
20
- };
21
- }
@@ -1,174 +0,0 @@
1
- import { ref, nextTick, onMounted, onUnmounted } from "vue";
2
-
3
- export function useDropdownPosition(dropdownRef, options = {}) {
4
- const menuStyle = ref({});
5
- const {
6
- offset = { x: -1, y: 4 },
7
- zIndex = 50000,
8
- minWidth = null,
9
- maxHeight = 160,
10
- estimateHeight = null,
11
- includeAdjacentButtons = false,
12
- containerSelector = null
13
- } = options;
14
-
15
- const calculateMenuPosition = () => {
16
- if (!dropdownRef.value) return;
17
-
18
- try {
19
- const rect = dropdownRef.value.getBoundingClientRect();
20
- const viewportHeight = window.innerHeight;
21
- const viewportWidth = window.innerWidth;
22
-
23
- // Calculate menu dimensions
24
- const menuHeight = estimateHeight ? estimateHeight() : maxHeight;
25
-
26
- // Calculate width including adjacent buttons if specified
27
- let menuWidth = minWidth || rect.width + 2;
28
-
29
- if (includeAdjacentButtons) {
30
- // Look for parent container with buttons
31
- const parentContainer = dropdownRef.value.closest(
32
- ".flex, .flex-responsive-wrap, .proxy-controls-row, .filter-controls, .dropdown-container"
33
- );
34
- if (parentContainer) {
35
- const containerRect = parentContainer.getBoundingClientRect();
36
- // Use the full container width for better alignment
37
- menuWidth = Math.max(menuWidth, containerRect.width);
38
- }
39
- }
40
-
41
- // Determine if menu should open upward
42
- const spaceBelow = viewportHeight - rect.bottom;
43
- const spaceAbove = rect.top;
44
- const openUpward = spaceBelow < menuHeight && spaceAbove > spaceBelow;
45
-
46
- // Calculate position with improved logic
47
- let top, left;
48
-
49
- if (openUpward) {
50
- // Position above with better spacing
51
- top = rect.top - menuHeight - Math.abs(offset.y) - 2;
52
- } else {
53
- // Position below with improved spacing
54
- top = rect.bottom + offset.y + 2;
55
- }
56
-
57
- // Improved horizontal positioning
58
- if (includeAdjacentButtons) {
59
- // Align with the start of the container for better visual consistency
60
- const parentContainer = dropdownRef.value.closest(
61
- ".flex, .flex-responsive-wrap, .proxy-controls-row, .filter-controls, .dropdown-container"
62
- );
63
- if (parentContainer) {
64
- const containerRect = parentContainer.getBoundingClientRect();
65
- left = containerRect.left + offset.x;
66
- } else {
67
- left = rect.left + offset.x;
68
- }
69
- } else {
70
- left = rect.left + offset.x;
71
- }
72
-
73
- // Enhanced boundary checking
74
- const padding = 12; // Increased padding from screen edges
75
-
76
- // Horizontal boundary checking
77
- if (left + menuWidth > viewportWidth - padding) {
78
- left = viewportWidth - menuWidth - padding;
79
- }
80
- if (left < padding) {
81
- left = padding;
82
- }
83
-
84
- // Vertical boundary checking with better logic
85
- if (top < padding) {
86
- top = padding;
87
- } else if (top + menuHeight > viewportHeight - padding) {
88
- if (openUpward) {
89
- // If opening upward and still doesn't fit, position at top
90
- top = padding;
91
- } else {
92
- // If opening downward and doesn't fit, try upward
93
- const upwardTop = rect.top - menuHeight - Math.abs(offset.y) - 2;
94
- if (upwardTop >= padding) {
95
- top = upwardTop;
96
- } else {
97
- // If neither direction fits well, center vertically
98
- top = Math.max(padding, (viewportHeight - menuHeight) / 2);
99
- }
100
- }
101
- }
102
-
103
- menuStyle.value = {
104
- position: "fixed",
105
- top: `${Math.round(top)}px`,
106
- left: `${Math.round(left)}px`,
107
- width: `${Math.round(menuWidth)}px`,
108
- zIndex,
109
- maxHeight: `${maxHeight}px`
110
- };
111
- } catch (error) {
112
- console.warn("Error calculating dropdown position:", error);
113
- // Fallback to basic positioning
114
- menuStyle.value = {
115
- position: "fixed",
116
- top: "0px",
117
- left: "0px",
118
- width: "200px",
119
- zIndex,
120
- maxHeight: `${maxHeight}px`
121
- };
122
- }
123
- };
124
-
125
- // Event handlers with ultra-smooth responsiveness using requestAnimationFrame
126
- let resizeFrame;
127
- const handleResize = () => {
128
- if (resizeFrame) {
129
- cancelAnimationFrame(resizeFrame);
130
- }
131
- resizeFrame = requestAnimationFrame(() => {
132
- calculateMenuPosition();
133
- });
134
- };
135
-
136
- let scrollFrame;
137
- const handleScroll = () => {
138
- if (scrollFrame) {
139
- cancelAnimationFrame(scrollFrame);
140
- }
141
- scrollFrame = requestAnimationFrame(() => {
142
- calculateMenuPosition();
143
- });
144
- };
145
-
146
- // Setup event listeners
147
- onMounted(() => {
148
- window.addEventListener("resize", handleResize, { passive: true });
149
- window.addEventListener("scroll", handleScroll, { passive: true, capture: true });
150
- });
151
-
152
- onUnmounted(() => {
153
- if (resizeFrame) {
154
- cancelAnimationFrame(resizeFrame);
155
- }
156
- if (scrollFrame) {
157
- cancelAnimationFrame(scrollFrame);
158
- }
159
- window.removeEventListener("resize", handleResize);
160
- window.removeEventListener("scroll", handleScroll, true);
161
- });
162
-
163
- const updatePosition = () => {
164
- nextTick(() => {
165
- calculateMenuPosition();
166
- });
167
- };
168
-
169
- return {
170
- menuStyle,
171
- updatePosition,
172
- calculateMenuPosition
173
- };
174
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * @typedef {Object} Task
3
- * @property {string} accountTag
4
- * @property {boolean} active
5
- * @property {boolean} agedAccount
6
- * @property {string} createdAt
7
- * @property {string} createdAt
8
- * @property {boolean} doNotPay
9
- * @property {string} email
10
- * @property {string} eventCity
11
- * @property {string} eventDate
12
- * @property {string} eventId
13
- * @property {string} eventImage
14
- * @property {string} eventLocalDate
15
- * @property {string} eventName
16
- * @property {string} eventUrl
17
- * @property {string} eventVenue
18
- * @property {string} expirationTime
19
- * @property {boolean} isExpanded
20
- * @property {boolean} loginAfterCart
21
- * @property {boolean} manual
22
- * @property {string} mode
23
- * @property {string} openerLink
24
- * @property {string} password
25
- * @property {string} presaleCode
26
- * @property {boolean} presaleMode
27
- * @property {string} profileName
28
- * @property {Array} profileTags
29
- * @property {string} proxy
30
- * @property {number} quantity
31
- * @property {boolean} quickQueue
32
- * @property {string} reservedTicketsList
33
- * @property {boolean} selected
34
- * @property {string} siteId
35
- * @property {boolean} smartTimer
36
- * @property {string} status
37
- * @property {string} statusColor
38
- * @property {string} taskId
39
- * @property {string} venueName
40
- * @property {string} _timeLeftString
41
- */
@@ -1 +0,0 @@
1
- export const DEBUG = window.location.href.includes(":5173");
package/switch-branch.sh DELETED
@@ -1,41 +0,0 @@
1
- #!/bin/bash
2
-
3
- # USAGE: ./git-force-switch.sh target-branch-name
4
-
5
- set -e
6
-
7
- TARGET_BRANCH="$1"
8
-
9
- if [ -z "$TARGET_BRANCH" ]; then
10
- echo "❌ Usage: $0 <branch-name>"
11
- exit 1
12
- fi
13
-
14
- echo "🔧 Forcing checkout to '$TARGET_BRANCH'..."
15
-
16
- # Step 1: Make sure Git respects case differences
17
- git config core.ignoreCase false
18
-
19
- # Step 2: Try checkout to see if it fails and capture errors
20
- ERROR_OUTPUT=$(git checkout "$TARGET_BRANCH" 2>&1) || true
21
-
22
- # Step 3: Check if it failed due to untracked files
23
- if echo "$ERROR_OUTPUT" | grep -q "would be overwritten by checkout"; then
24
- echo "⚠️ Conflicting untracked files detected. Cleaning them up..."
25
-
26
- # Extract file paths and delete them
27
- echo "$ERROR_OUTPUT" |
28
- grep "^\s" |
29
- sed 's/^[ \t]*//' |
30
- while read -r FILE; do
31
- if [ -f "$FILE" ] || [ -d "$FILE" ]; then
32
- echo "🗑️ Removing $FILE"
33
- rm -rf "$FILE"
34
- fi
35
- done
36
-
37
- echo "🔁 Retrying checkout..."
38
- git checkout "$TARGET_BRANCH"
39
- else
40
- echo "✅ Switched to $TARGET_BRANCH successfully."
41
- fi
@@ -1,63 +0,0 @@
1
- module.exports = {
2
- globDirectory: "public/",
3
- globPatterns: ["**/*.{png,ico,svg,jpg,jpeg,webp}", "manifest.json"],
4
- swDest: "public/sw.js",
5
- sourcemap: false,
6
- skipWaiting: true,
7
- clientsClaim: true,
8
- ignoreURLParametersMatching: [/^utm_/, /^fbclid$/],
9
- cleanupOutdatedCaches: true,
10
- runtimeCaching: [
11
- {
12
- urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp|ico)$/,
13
- handler: "CacheFirst",
14
- options: {
15
- cacheName: "images",
16
- expiration: {
17
- maxEntries: 150,
18
- maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
19
- }
20
- }
21
- },
22
- {
23
- urlPattern: /\.(?:js|css)$/,
24
- handler: "StaleWhileRevalidate",
25
- options: {
26
- cacheName: "static-resources",
27
- expiration: {
28
- maxEntries: 50,
29
- maxAgeSeconds: 60 * 60 * 24 * 7 // 1 week
30
- }
31
- }
32
- },
33
- {
34
- urlPattern: /^https:\/\/fonts\.googleapis\.com\//,
35
- handler: "StaleWhileRevalidate",
36
- options: {
37
- cacheName: "google-fonts-stylesheets"
38
- }
39
- },
40
- {
41
- urlPattern: /^https:\/\/fonts\.gstatic\.com\//,
42
- handler: "CacheFirst",
43
- options: {
44
- cacheName: "google-fonts-webfonts",
45
- expiration: {
46
- maxEntries: 10,
47
- maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year
48
- }
49
- }
50
- },
51
- {
52
- urlPattern: /\/flags\//,
53
- handler: "CacheFirst",
54
- options: {
55
- cacheName: "country-flags",
56
- expiration: {
57
- maxEntries: 50,
58
- maxAgeSeconds: 60 * 60 * 24 * 90 // 90 days
59
- }
60
- }
61
- }
62
- ]
63
- };