@mongoosejs/studio 0.3.5 → 0.3.7
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.
- package/backend/actions/ChatThread/createChatMessage.js +12 -2
- package/backend/actions/ChatThread/streamChatMessage.js +12 -2
- package/backend/actions/Model/createChatMessage.js +12 -2
- package/backend/actions/Model/streamChatMessage.js +13 -2
- package/backend/actions/Task/getTasksOverTime.js +66 -0
- package/backend/actions/Task/index.js +1 -0
- package/frontend/public/app.js +809 -110
- package/frontend/public/tw.css +19 -16
- package/frontend/src/api.js +6 -0
- package/frontend/src/chat/chat.html +19 -12
- package/frontend/src/chat/chat.js +9 -3
- package/frontend/src/create-document/create-document.js +3 -1
- package/frontend/src/dashboard-result/dashboard-primitive/dashboard-primitive.html +2 -2
- package/frontend/src/dashboard-result/dashboard-primitive/dashboard-primitive.js +13 -1
- package/frontend/src/dashboard-result/dashboard-result.html +1 -1
- package/frontend/src/dashboard-result/dashboard-table/dashboard-table.html +21 -1
- package/frontend/src/dashboard-result/dashboard-table/dashboard-table.js +52 -0
- package/frontend/src/detail-date/detail-date.html +1 -0
- package/frontend/src/detail-date/detail-date.js +123 -0
- package/frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.html +26 -0
- package/frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.js +41 -0
- package/frontend/src/document-details/document-property/document-property.html +13 -5
- package/frontend/src/document-details/document-property/document-property.js +14 -1
- package/frontend/src/getCurrentDateTimeContext.js +17 -0
- package/frontend/src/list-json/list-json.js +0 -7
- package/frontend/src/modal/modal.js +25 -1
- package/frontend/src/models/document-search/document-search.js +3 -0
- package/frontend/src/models/models.html +25 -5
- package/frontend/src/models/models.js +1 -1
- package/frontend/src/navbar/navbar.html +6 -1
- package/frontend/src/navbar/navbar.js +1 -6
- package/frontend/src/pro-upgrade-modal/pro-upgrade-modal.html +38 -0
- package/frontend/src/pro-upgrade-modal/pro-upgrade-modal.js +23 -0
- package/frontend/src/tasks/tasks.html +34 -20
- package/frontend/src/tasks/tasks.js +158 -5
- package/local.js +2 -1
- package/package.json +2 -1
package/frontend/public/app.js
CHANGED
|
@@ -814,6 +814,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
814
814
|
getTaskOverview: function getTaskOverview(params) {
|
|
815
815
|
return client.post('', { action: 'Task.getTaskOverview', ...params }).then(res => res.data);
|
|
816
816
|
},
|
|
817
|
+
getTasksOverTime: function getTasksOverTime(params) {
|
|
818
|
+
return client.post('', { action: 'Task.getTasksOverTime', ...params }).then(res => res.data);
|
|
819
|
+
},
|
|
817
820
|
rescheduleTask: function rescheduleTask(params) {
|
|
818
821
|
return client.post('', { action: 'Task.rescheduleTask', ...params }).then(res => res.data);
|
|
819
822
|
},
|
|
@@ -1154,6 +1157,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
1154
1157
|
getTaskOverview: function getTaskOverview(params) {
|
|
1155
1158
|
return client.post('/Task/getTaskOverview', params).then(res => res.data);
|
|
1156
1159
|
},
|
|
1160
|
+
getTasksOverTime: function getTasksOverTime(params) {
|
|
1161
|
+
return client.post('/Task/getTasksOverTime', params).then(res => res.data);
|
|
1162
|
+
},
|
|
1157
1163
|
rescheduleTask: function rescheduleTask(params) {
|
|
1158
1164
|
return client.post('/Task/rescheduleTask', params).then(res => res.data);
|
|
1159
1165
|
},
|
|
@@ -1637,6 +1643,7 @@ module.exports = app => app.component('chat-message', {
|
|
|
1637
1643
|
|
|
1638
1644
|
|
|
1639
1645
|
const api = __webpack_require__(/*! ../api */ "./frontend/src/api.js");
|
|
1646
|
+
const getCurrentDateTimeContext = __webpack_require__(/*! ../getCurrentDateTimeContext */ "./frontend/src/getCurrentDateTimeContext.js");
|
|
1640
1647
|
const template = __webpack_require__(/*! ./chat.html */ "./frontend/src/chat/chat.html");
|
|
1641
1648
|
|
|
1642
1649
|
module.exports = {
|
|
@@ -1651,7 +1658,8 @@ module.exports = {
|
|
|
1651
1658
|
chatMessages: [],
|
|
1652
1659
|
hideSidebar: null,
|
|
1653
1660
|
sharingThread: false,
|
|
1654
|
-
threadSearch: ''
|
|
1661
|
+
threadSearch: '',
|
|
1662
|
+
showProUpgradeModal: false
|
|
1655
1663
|
}),
|
|
1656
1664
|
methods: {
|
|
1657
1665
|
async sendMessage() {
|
|
@@ -1680,7 +1688,11 @@ module.exports = {
|
|
|
1680
1688
|
}
|
|
1681
1689
|
});
|
|
1682
1690
|
|
|
1683
|
-
const params = {
|
|
1691
|
+
const params = {
|
|
1692
|
+
chatThreadId: this.chatThreadId,
|
|
1693
|
+
content,
|
|
1694
|
+
currentDateTime: getCurrentDateTimeContext()
|
|
1695
|
+
};
|
|
1684
1696
|
let userChatMessage = null;
|
|
1685
1697
|
let assistantChatMessage = null;
|
|
1686
1698
|
for await (const event of api.ChatThread.streamChatMessage(params)) {
|
|
@@ -1787,7 +1799,7 @@ module.exports = {
|
|
|
1787
1799
|
},
|
|
1788
1800
|
async toggleShareThread() {
|
|
1789
1801
|
if (!this.chatThreadId || !this.hasWorkspace) {
|
|
1790
|
-
|
|
1802
|
+
throw new Error('Cannot share thread: chatThreadId or hasWorkspace is missing');
|
|
1791
1803
|
}
|
|
1792
1804
|
this.sharingThread = true;
|
|
1793
1805
|
try {
|
|
@@ -2001,6 +2013,7 @@ const ObjectId = new Proxy(BSON.ObjectId, {
|
|
|
2001
2013
|
});
|
|
2002
2014
|
|
|
2003
2015
|
const appendCSS = __webpack_require__(/*! ../appendCSS */ "./frontend/src/appendCSS.js");
|
|
2016
|
+
const getCurrentDateTimeContext = __webpack_require__(/*! ../getCurrentDateTimeContext */ "./frontend/src/getCurrentDateTimeContext.js");
|
|
2004
2017
|
|
|
2005
2018
|
appendCSS(__webpack_require__(/*! ./create-document.css */ "./frontend/src/create-document/create-document.css"));
|
|
2006
2019
|
|
|
@@ -2039,7 +2052,8 @@ module.exports = app => app.component('create-document', {
|
|
|
2039
2052
|
for await (const event of api.Model.streamChatMessage({
|
|
2040
2053
|
model: this.currentModel,
|
|
2041
2054
|
content: prompt,
|
|
2042
|
-
documentData: this.aiOriginalDocument
|
|
2055
|
+
documentData: this.aiOriginalDocument,
|
|
2056
|
+
currentDateTime: getCurrentDateTimeContext()
|
|
2043
2057
|
})) {
|
|
2044
2058
|
if (event?.textPart) {
|
|
2045
2059
|
this.aiSuggestion += event.textPart;
|
|
@@ -2434,16 +2448,28 @@ module.exports = app => app.component('dashboard-primitive', {
|
|
|
2434
2448
|
props: ['value'],
|
|
2435
2449
|
computed: {
|
|
2436
2450
|
header() {
|
|
2437
|
-
if (this.value != null && this.value.$primitive
|
|
2451
|
+
if (this.value != null && this.value.$primitive?.header) {
|
|
2438
2452
|
return this.value.$primitive.header;
|
|
2439
2453
|
}
|
|
2440
2454
|
return null;
|
|
2441
2455
|
},
|
|
2442
2456
|
displayValue() {
|
|
2443
2457
|
if (this.value != null && this.value.$primitive) {
|
|
2458
|
+
if (this.value.$primitive.value === null) {
|
|
2459
|
+
return 'null';
|
|
2460
|
+
}
|
|
2444
2461
|
return this.value.$primitive.value;
|
|
2445
2462
|
}
|
|
2463
|
+
if (this.value === null) {
|
|
2464
|
+
return 'null';
|
|
2465
|
+
}
|
|
2446
2466
|
return this.value;
|
|
2467
|
+
},
|
|
2468
|
+
displayClass() {
|
|
2469
|
+
if (this.value == null) {
|
|
2470
|
+
return 'text-content-tertiary';
|
|
2471
|
+
}
|
|
2472
|
+
return null;
|
|
2447
2473
|
}
|
|
2448
2474
|
}
|
|
2449
2475
|
});
|
|
@@ -2512,6 +2538,7 @@ module.exports = app => app.component('dashboard-result', {
|
|
|
2512
2538
|
(module, __unused_webpack_exports, __webpack_require__) {
|
|
2513
2539
|
|
|
2514
2540
|
"use strict";
|
|
2541
|
+
/* global Blob, URL, document */
|
|
2515
2542
|
|
|
2516
2543
|
|
|
2517
2544
|
const template = __webpack_require__(/*! ./dashboard-table.html */ "./frontend/src/dashboard-result/dashboard-table/dashboard-table.html");
|
|
@@ -2519,6 +2546,11 @@ const template = __webpack_require__(/*! ./dashboard-table.html */ "./frontend/s
|
|
|
2519
2546
|
module.exports = app => app.component('dashboard-table', {
|
|
2520
2547
|
template,
|
|
2521
2548
|
props: ['value'],
|
|
2549
|
+
data() {
|
|
2550
|
+
return {
|
|
2551
|
+
showDropdown: false
|
|
2552
|
+
};
|
|
2553
|
+
},
|
|
2522
2554
|
computed: {
|
|
2523
2555
|
columns() {
|
|
2524
2556
|
return Array.isArray(this.value?.$table?.columns) ? this.value.$table.columns : [];
|
|
@@ -2534,6 +2566,46 @@ module.exports = app => app.component('dashboard-table', {
|
|
|
2534
2566
|
}
|
|
2535
2567
|
},
|
|
2536
2568
|
methods: {
|
|
2569
|
+
toggleDropdown() {
|
|
2570
|
+
this.showDropdown = !this.showDropdown;
|
|
2571
|
+
},
|
|
2572
|
+
handleBodyClick(event) {
|
|
2573
|
+
const dropdownRefs = this.$refs.dropdown;
|
|
2574
|
+
const dropdowns = Array.isArray(dropdownRefs) ? dropdownRefs : [dropdownRefs];
|
|
2575
|
+
const hasClickInsideDropdown = dropdowns
|
|
2576
|
+
.filter(dropdown => dropdown && typeof dropdown.contains === 'function')
|
|
2577
|
+
.some(dropdown => dropdown.contains(event.target));
|
|
2578
|
+
|
|
2579
|
+
if (!hasClickInsideDropdown) {
|
|
2580
|
+
this.showDropdown = false;
|
|
2581
|
+
}
|
|
2582
|
+
},
|
|
2583
|
+
neutralizeCsvCell(cell) {
|
|
2584
|
+
const value = this.displayValue(cell);
|
|
2585
|
+
return /^\s*[=+\-@]/.test(value) ? `'${value}` : value;
|
|
2586
|
+
},
|
|
2587
|
+
escapeCsvCell(cell) {
|
|
2588
|
+
const escapedCell = this.neutralizeCsvCell(cell).replaceAll('"', '""');
|
|
2589
|
+
return `"${escapedCell}"`;
|
|
2590
|
+
},
|
|
2591
|
+
downloadCsv() {
|
|
2592
|
+
const header = this.columns.map(this.escapeCsvCell).join(',');
|
|
2593
|
+
const rows = this.rows
|
|
2594
|
+
.map(row => row.map(this.escapeCsvCell).join(','))
|
|
2595
|
+
.join('\n');
|
|
2596
|
+
|
|
2597
|
+
const csv = [header, rows].filter(v => v.length > 0).join('\n');
|
|
2598
|
+
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
|
2599
|
+
const url = URL.createObjectURL(blob);
|
|
2600
|
+
const anchor = document.createElement('a');
|
|
2601
|
+
anchor.href = url;
|
|
2602
|
+
anchor.download = 'table.csv';
|
|
2603
|
+
document.body.appendChild(anchor);
|
|
2604
|
+
anchor.click();
|
|
2605
|
+
document.body.removeChild(anchor);
|
|
2606
|
+
URL.revokeObjectURL(url);
|
|
2607
|
+
this.$toast.success('CSV downloaded!');
|
|
2608
|
+
},
|
|
2537
2609
|
displayValue(cell) {
|
|
2538
2610
|
if (cell == null) {
|
|
2539
2611
|
return '';
|
|
@@ -2547,6 +2619,12 @@ module.exports = app => app.component('dashboard-table', {
|
|
|
2547
2619
|
}
|
|
2548
2620
|
return String(cell);
|
|
2549
2621
|
}
|
|
2622
|
+
},
|
|
2623
|
+
mounted() {
|
|
2624
|
+
document.body.addEventListener('click', this.handleBodyClick);
|
|
2625
|
+
},
|
|
2626
|
+
unmounted() {
|
|
2627
|
+
document.body.removeEventListener('click', this.handleBodyClick);
|
|
2550
2628
|
}
|
|
2551
2629
|
});
|
|
2552
2630
|
|
|
@@ -2932,6 +3010,140 @@ module.exports = app => app.component('detail-array', {
|
|
|
2932
3010
|
}
|
|
2933
3011
|
});
|
|
2934
3012
|
|
|
3013
|
+
/***/ },
|
|
3014
|
+
|
|
3015
|
+
/***/ "./frontend/src/detail-date/detail-date.js"
|
|
3016
|
+
/*!*************************************************!*\
|
|
3017
|
+
!*** ./frontend/src/detail-date/detail-date.js ***!
|
|
3018
|
+
\*************************************************/
|
|
3019
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3020
|
+
|
|
3021
|
+
"use strict";
|
|
3022
|
+
|
|
3023
|
+
|
|
3024
|
+
const template = __webpack_require__(/*! ./detail-date.html */ "./frontend/src/detail-date/detail-date.html");
|
|
3025
|
+
|
|
3026
|
+
module.exports = app => app.component('detail-date', {
|
|
3027
|
+
template,
|
|
3028
|
+
props: ['value', 'viewMode'],
|
|
3029
|
+
emits: ['updated'],
|
|
3030
|
+
watch: {
|
|
3031
|
+
displayValue: {
|
|
3032
|
+
immediate: true,
|
|
3033
|
+
handler(val) {
|
|
3034
|
+
this.$emit('updated', val);
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
},
|
|
3038
|
+
computed: {
|
|
3039
|
+
format() {
|
|
3040
|
+
if (this.viewMode != null && typeof this.viewMode === 'object') {
|
|
3041
|
+
return this.viewMode.format;
|
|
3042
|
+
}
|
|
3043
|
+
return this.viewMode;
|
|
3044
|
+
},
|
|
3045
|
+
timezone() {
|
|
3046
|
+
if (this.viewMode != null && typeof this.viewMode === 'object') {
|
|
3047
|
+
return this.viewMode.timezone || '';
|
|
3048
|
+
}
|
|
3049
|
+
return '';
|
|
3050
|
+
},
|
|
3051
|
+
parsedDate() {
|
|
3052
|
+
if (this.value == null) {
|
|
3053
|
+
return null;
|
|
3054
|
+
}
|
|
3055
|
+
const date = new Date(this.value);
|
|
3056
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
3057
|
+
},
|
|
3058
|
+
displayValue() {
|
|
3059
|
+
if (this.value == null) {
|
|
3060
|
+
return String(this.value);
|
|
3061
|
+
}
|
|
3062
|
+
if (!this.parsedDate) {
|
|
3063
|
+
return 'Invalid Date';
|
|
3064
|
+
}
|
|
3065
|
+
return this.formatDateForDisplay(this.parsedDate);
|
|
3066
|
+
}
|
|
3067
|
+
},
|
|
3068
|
+
methods: {
|
|
3069
|
+
formatDateForDisplay(date) {
|
|
3070
|
+
if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
|
|
3071
|
+
return 'Invalid Date';
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
if (this.format === 'utc_iso') {
|
|
3075
|
+
return date.toISOString();
|
|
3076
|
+
}
|
|
3077
|
+
|
|
3078
|
+
if (this.format === 'local_browser') {
|
|
3079
|
+
return date.toLocaleString();
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
if (this.format === 'unix_ms') {
|
|
3083
|
+
return String(date.getTime());
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
if (this.format === 'unix_seconds') {
|
|
3087
|
+
return String(Math.floor(date.getTime() / 1000));
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3090
|
+
if (this.format === 'duration_relative') {
|
|
3091
|
+
return this.formatRelativeDuration(date);
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
if (this.format === 'custom_tz') {
|
|
3095
|
+
return this.formatCustomTimezone(date);
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
return date.toISOString();
|
|
3099
|
+
},
|
|
3100
|
+
formatRelativeDuration(date) {
|
|
3101
|
+
const diffMs = date.getTime() - Date.now();
|
|
3102
|
+
const absMs = Math.abs(diffMs);
|
|
3103
|
+
const rtf = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });
|
|
3104
|
+
const units = [
|
|
3105
|
+
{ unit: 'year', ms: 365 * 24 * 60 * 60 * 1000 },
|
|
3106
|
+
{ unit: 'month', ms: 30 * 24 * 60 * 60 * 1000 },
|
|
3107
|
+
{ unit: 'day', ms: 24 * 60 * 60 * 1000 },
|
|
3108
|
+
{ unit: 'hour', ms: 60 * 60 * 1000 },
|
|
3109
|
+
{ unit: 'minute', ms: 60 * 1000 },
|
|
3110
|
+
{ unit: 'second', ms: 1000 }
|
|
3111
|
+
];
|
|
3112
|
+
|
|
3113
|
+
for (const { unit, ms } of units) {
|
|
3114
|
+
if (absMs >= ms || unit === 'second') {
|
|
3115
|
+
const value = Math.round(diffMs / ms);
|
|
3116
|
+
return rtf.format(value, unit);
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
|
|
3120
|
+
return 'now';
|
|
3121
|
+
},
|
|
3122
|
+
formatCustomTimezone(date) {
|
|
3123
|
+
const tz = (this.timezone || '').trim();
|
|
3124
|
+
if (!tz) {
|
|
3125
|
+
return `${date.toISOString()} (enter an IANA timezone)`;
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
try {
|
|
3129
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
3130
|
+
timeZone: tz,
|
|
3131
|
+
year: 'numeric',
|
|
3132
|
+
month: '2-digit',
|
|
3133
|
+
day: '2-digit',
|
|
3134
|
+
hour: '2-digit',
|
|
3135
|
+
minute: '2-digit',
|
|
3136
|
+
second: '2-digit',
|
|
3137
|
+
timeZoneName: 'short'
|
|
3138
|
+
}).format(date);
|
|
3139
|
+
} catch (err) {
|
|
3140
|
+
return `Invalid timezone: ${tz}`;
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
});
|
|
3145
|
+
|
|
3146
|
+
|
|
2935
3147
|
/***/ },
|
|
2936
3148
|
|
|
2937
3149
|
/***/ "./frontend/src/detail-default/detail-default.js"
|
|
@@ -4056,6 +4268,58 @@ module.exports = app => app.component('detail-default', {
|
|
|
4056
4268
|
});
|
|
4057
4269
|
|
|
4058
4270
|
|
|
4271
|
+
/***/ },
|
|
4272
|
+
|
|
4273
|
+
/***/ "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.js"
|
|
4274
|
+
/*!**************************************************************************************!*\
|
|
4275
|
+
!*** ./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.js ***!
|
|
4276
|
+
\**************************************************************************************/
|
|
4277
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
4278
|
+
|
|
4279
|
+
"use strict";
|
|
4280
|
+
|
|
4281
|
+
|
|
4282
|
+
const template = __webpack_require__(/*! ./date-view-mode-picker.html */ "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.html");
|
|
4283
|
+
|
|
4284
|
+
module.exports = app => app.component('date-view-mode-picker', {
|
|
4285
|
+
template,
|
|
4286
|
+
props: ['viewMode', 'path'],
|
|
4287
|
+
emits: ['update:viewMode'],
|
|
4288
|
+
computed: {
|
|
4289
|
+
format() {
|
|
4290
|
+
if (this.viewMode != null && typeof this.viewMode === 'object') {
|
|
4291
|
+
return this.viewMode.format;
|
|
4292
|
+
}
|
|
4293
|
+
return this.viewMode;
|
|
4294
|
+
},
|
|
4295
|
+
timezone() {
|
|
4296
|
+
if (this.viewMode != null && typeof this.viewMode === 'object') {
|
|
4297
|
+
return this.viewMode.timezone || '';
|
|
4298
|
+
}
|
|
4299
|
+
return '';
|
|
4300
|
+
},
|
|
4301
|
+
timezoneDatalistId() {
|
|
4302
|
+
return `timezone-options-${String(this.path?.path || '').replace(/[^a-zA-Z0-9_-]/g, '-')}`;
|
|
4303
|
+
},
|
|
4304
|
+
timezones() {
|
|
4305
|
+
return Intl.supportedValuesOf('timeZone');
|
|
4306
|
+
}
|
|
4307
|
+
},
|
|
4308
|
+
methods: {
|
|
4309
|
+
onFormatChange(newFormat) {
|
|
4310
|
+
if (newFormat === 'custom_tz') {
|
|
4311
|
+
this.$emit('update:viewMode', { format: 'custom_tz', timezone: this.timezone });
|
|
4312
|
+
} else {
|
|
4313
|
+
this.$emit('update:viewMode', newFormat);
|
|
4314
|
+
}
|
|
4315
|
+
},
|
|
4316
|
+
onTimezoneChange(newTimezone) {
|
|
4317
|
+
this.$emit('update:viewMode', { format: 'custom_tz', timezone: newTimezone });
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
});
|
|
4321
|
+
|
|
4322
|
+
|
|
4059
4323
|
/***/ },
|
|
4060
4324
|
|
|
4061
4325
|
/***/ "./frontend/src/document-details/document-details.js"
|
|
@@ -4520,11 +4784,15 @@ const appendCSS = __webpack_require__(/*! ../../appendCSS */ "./frontend/src/app
|
|
|
4520
4784
|
|
|
4521
4785
|
appendCSS(__webpack_require__(/*! ./document-property.css */ "./frontend/src/document-details/document-property/document-property.css"));
|
|
4522
4786
|
|
|
4787
|
+
const UNSET = Symbol('unset');
|
|
4788
|
+
|
|
4523
4789
|
module.exports = app => app.component('document-property', {
|
|
4524
4790
|
template,
|
|
4525
4791
|
data: function() {
|
|
4526
4792
|
return {
|
|
4527
4793
|
dateType: 'picker', // picker, iso
|
|
4794
|
+
dateViewMode: 'utc_iso',
|
|
4795
|
+
renderedValue: UNSET,
|
|
4528
4796
|
isCollapsed: false, // Start uncollapsed by default
|
|
4529
4797
|
isValueExpanded: false, // Track if the value is expanded
|
|
4530
4798
|
detailViewMode: 'text',
|
|
@@ -4541,8 +4809,14 @@ module.exports = app => app.component('document-property', {
|
|
|
4541
4809
|
},
|
|
4542
4810
|
props: ['path', 'document', 'schemaPaths', 'editting', 'changes', 'invalid', 'highlight'],
|
|
4543
4811
|
computed: {
|
|
4812
|
+
isDatePath() {
|
|
4813
|
+
return this.path?.instance === 'Date';
|
|
4814
|
+
},
|
|
4815
|
+
rawValue() {
|
|
4816
|
+
return this.getValueForPath(this.path.path);
|
|
4817
|
+
},
|
|
4544
4818
|
valueAsString() {
|
|
4545
|
-
const value = this.
|
|
4819
|
+
const value = this.renderedValue !== UNSET ? this.renderedValue : this.rawValue;
|
|
4546
4820
|
if (value == null) {
|
|
4547
4821
|
return String(value);
|
|
4548
4822
|
}
|
|
@@ -4674,6 +4948,9 @@ module.exports = app => app.component('document-property', {
|
|
|
4674
4948
|
if (schemaPath.instance === 'Array') {
|
|
4675
4949
|
return 'detail-array';
|
|
4676
4950
|
}
|
|
4951
|
+
if (schemaPath.instance === 'Date') {
|
|
4952
|
+
return 'detail-date';
|
|
4953
|
+
}
|
|
4677
4954
|
return 'detail-default';
|
|
4678
4955
|
},
|
|
4679
4956
|
getEditComponentForPath(path) {
|
|
@@ -5887,6 +6164,34 @@ exports.isoToLongDateTime = function isoToLongDateTime(str) {
|
|
|
5887
6164
|
};
|
|
5888
6165
|
|
|
5889
6166
|
|
|
6167
|
+
/***/ },
|
|
6168
|
+
|
|
6169
|
+
/***/ "./frontend/src/getCurrentDateTimeContext.js"
|
|
6170
|
+
/*!***************************************************!*\
|
|
6171
|
+
!*** ./frontend/src/getCurrentDateTimeContext.js ***!
|
|
6172
|
+
\***************************************************/
|
|
6173
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
6174
|
+
|
|
6175
|
+
"use strict";
|
|
6176
|
+
|
|
6177
|
+
|
|
6178
|
+
const time = __webpack_require__(/*! time-commando */ "./node_modules/time-commando/index.js");
|
|
6179
|
+
|
|
6180
|
+
module.exports = function getCurrentDateTimeContext() {
|
|
6181
|
+
const date = time.now();
|
|
6182
|
+
const components = [
|
|
6183
|
+
date.getFullYear(),
|
|
6184
|
+
date.getMonth() + 1,
|
|
6185
|
+
date.getDate(),
|
|
6186
|
+
date.getHours(),
|
|
6187
|
+
date.getMinutes(),
|
|
6188
|
+
date.getSeconds()
|
|
6189
|
+
].map(num => num.toString().padStart(2, '0'));
|
|
6190
|
+
const [yyyy, mm, dd, hh, mi, ss] = components;
|
|
6191
|
+
return `${yyyy}-${mm}-${dd}T${hh}:${mi}:${ss}`;
|
|
6192
|
+
};
|
|
6193
|
+
|
|
6194
|
+
|
|
5890
6195
|
/***/ },
|
|
5891
6196
|
|
|
5892
6197
|
/***/ "./frontend/src/index.js"
|
|
@@ -6551,13 +6856,6 @@ module.exports = app => app.component('list-json', {
|
|
|
6551
6856
|
topLevelExpanded: false
|
|
6552
6857
|
};
|
|
6553
6858
|
},
|
|
6554
|
-
watch: {
|
|
6555
|
-
value: {
|
|
6556
|
-
handler() {
|
|
6557
|
-
this.resetCollapse();
|
|
6558
|
-
}
|
|
6559
|
-
}
|
|
6560
|
-
},
|
|
6561
6859
|
created() {
|
|
6562
6860
|
this.resetCollapse();
|
|
6563
6861
|
for (const field of this.expandedFields) {
|
|
@@ -6758,7 +7056,31 @@ appendCSS(__webpack_require__(/*! ./modal.css */ "./frontend/src/modal/modal.css
|
|
|
6758
7056
|
|
|
6759
7057
|
module.exports = app => app.component('modal', {
|
|
6760
7058
|
template,
|
|
6761
|
-
props: ['containerClass']
|
|
7059
|
+
props: ['containerClass'],
|
|
7060
|
+
mounted() {
|
|
7061
|
+
window.addEventListener('keydown', this.onEscape);
|
|
7062
|
+
},
|
|
7063
|
+
beforeUnmount() {
|
|
7064
|
+
window.removeEventListener('keydown', this.onEscape);
|
|
7065
|
+
},
|
|
7066
|
+
methods: {
|
|
7067
|
+
onEscape(event) {
|
|
7068
|
+
if (event.key !== 'Escape') {
|
|
7069
|
+
return;
|
|
7070
|
+
}
|
|
7071
|
+
|
|
7072
|
+
const modalMasks = Array.from(document.querySelectorAll('.modal-mask'));
|
|
7073
|
+
const currentMask = this.$el?.classList?.contains('modal-mask') ? this.$el : this.$el?.querySelector('.modal-mask') || this.$el;
|
|
7074
|
+
const isTopMostModal = modalMasks.length > 0 && modalMasks[modalMasks.length - 1] === currentMask;
|
|
7075
|
+
|
|
7076
|
+
if (!isTopMostModal) {
|
|
7077
|
+
return;
|
|
7078
|
+
}
|
|
7079
|
+
|
|
7080
|
+
const closeButton = currentMask.querySelector('.modal-exit, [data-modal-close]');
|
|
7081
|
+
closeButton?.click();
|
|
7082
|
+
}
|
|
7083
|
+
}
|
|
6762
7084
|
});
|
|
6763
7085
|
|
|
6764
7086
|
|
|
@@ -6814,6 +7136,9 @@ module.exports = app => app.component('document-search', {
|
|
|
6814
7136
|
created() {
|
|
6815
7137
|
this.buildAutocompleteTrie();
|
|
6816
7138
|
},
|
|
7139
|
+
mounted() {
|
|
7140
|
+
this.$refs.searchInput.focus();
|
|
7141
|
+
},
|
|
6817
7142
|
methods: {
|
|
6818
7143
|
emitSearch() {
|
|
6819
7144
|
this.$emit('input', this.searchText);
|
|
@@ -7312,7 +7637,7 @@ module.exports = app => app.component('models', {
|
|
|
7312
7637
|
computed: {
|
|
7313
7638
|
referenceMap() {
|
|
7314
7639
|
const map = {};
|
|
7315
|
-
for (const path of this.
|
|
7640
|
+
for (const path of this.schemaPaths) {
|
|
7316
7641
|
if (path?.ref) {
|
|
7317
7642
|
map[path.path] = path.ref;
|
|
7318
7643
|
}
|
|
@@ -8789,12 +9114,7 @@ module.exports = app => app.component('navbar', {
|
|
|
8789
9114
|
return this.roles && this.roles[0] === 'dashboards' ? 'dashboards' : 'root';
|
|
8790
9115
|
},
|
|
8791
9116
|
hasTaskVisualizer() {
|
|
8792
|
-
|
|
8793
|
-
return '#/tasks';
|
|
8794
|
-
} else {
|
|
8795
|
-
return 'https://www.npmjs.com/package/@mongoosejs/task';
|
|
8796
|
-
}
|
|
8797
|
-
|
|
9117
|
+
return !!window.MONGOOSE_STUDIO_CONFIG.enableTaskVisualizer;
|
|
8798
9118
|
}
|
|
8799
9119
|
},
|
|
8800
9120
|
methods: {
|
|
@@ -8848,6 +9168,40 @@ module.exports = app => app.component('navbar', {
|
|
|
8848
9168
|
});
|
|
8849
9169
|
|
|
8850
9170
|
|
|
9171
|
+
/***/ },
|
|
9172
|
+
|
|
9173
|
+
/***/ "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.js"
|
|
9174
|
+
/*!*************************************************************!*\
|
|
9175
|
+
!*** ./frontend/src/pro-upgrade-modal/pro-upgrade-modal.js ***!
|
|
9176
|
+
\*************************************************************/
|
|
9177
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
9178
|
+
|
|
9179
|
+
"use strict";
|
|
9180
|
+
|
|
9181
|
+
|
|
9182
|
+
const template = __webpack_require__(/*! ./pro-upgrade-modal.html */ "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.html");
|
|
9183
|
+
|
|
9184
|
+
module.exports = app => app.component('pro-upgrade-modal', {
|
|
9185
|
+
template,
|
|
9186
|
+
props: {
|
|
9187
|
+
show: { type: Boolean, default: false },
|
|
9188
|
+
featureDescription: { type: String, default: 'This feature is available on the Pro plan.' }
|
|
9189
|
+
},
|
|
9190
|
+
emits: ['close'],
|
|
9191
|
+
watch: {
|
|
9192
|
+
show(val) {
|
|
9193
|
+
if (val) {
|
|
9194
|
+
this.$nextTick(() => {
|
|
9195
|
+
if (this.$refs.overlay) {
|
|
9196
|
+
this.$refs.overlay.focus();
|
|
9197
|
+
}
|
|
9198
|
+
});
|
|
9199
|
+
}
|
|
9200
|
+
}
|
|
9201
|
+
}
|
|
9202
|
+
});
|
|
9203
|
+
|
|
9204
|
+
|
|
8851
9205
|
/***/ },
|
|
8852
9206
|
|
|
8853
9207
|
/***/ "./frontend/src/routes.js"
|
|
@@ -9666,6 +10020,39 @@ const template = __webpack_require__(/*! ./tasks.html */ "./frontend/src/tasks/t
|
|
|
9666
10020
|
const api = __webpack_require__(/*! ../api */ "./frontend/src/api.js");
|
|
9667
10021
|
const { DATE_FILTERS, getDateRangeForRange } = __webpack_require__(/*! ../_util/dateRange */ "./frontend/src/_util/dateRange.js");
|
|
9668
10022
|
|
|
10023
|
+
/** Returns the bucket size in ms for the given date range. */
|
|
10024
|
+
function getBucketSizeMs(range) {
|
|
10025
|
+
switch (range) {
|
|
10026
|
+
case 'last_hour': return 5 * 60 * 1000; // 5 minutes
|
|
10027
|
+
case 'today':
|
|
10028
|
+
case 'yesterday': return 60 * 60 * 1000; // 1 hour
|
|
10029
|
+
case 'thisWeek':
|
|
10030
|
+
case 'lastWeek': return 24 * 60 * 60 * 1000; // 1 day
|
|
10031
|
+
case 'thisMonth':
|
|
10032
|
+
case 'lastMonth': return 24 * 60 * 60 * 1000; // 1 day
|
|
10033
|
+
default: return 5 * 60 * 1000;
|
|
10034
|
+
}
|
|
10035
|
+
}
|
|
10036
|
+
|
|
10037
|
+
/** Formats a bucket timestamp for the x-axis label based on the date range. */
|
|
10038
|
+
function formatBucketLabel(timestamp, range) {
|
|
10039
|
+
const date = new Date(timestamp);
|
|
10040
|
+
switch (range) {
|
|
10041
|
+
case 'last_hour':
|
|
10042
|
+
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
10043
|
+
case 'today':
|
|
10044
|
+
case 'yesterday':
|
|
10045
|
+
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
10046
|
+
case 'thisWeek':
|
|
10047
|
+
case 'lastWeek':
|
|
10048
|
+
case 'thisMonth':
|
|
10049
|
+
case 'lastMonth':
|
|
10050
|
+
return date.toLocaleDateString([], { month: 'short', day: 'numeric' });
|
|
10051
|
+
default:
|
|
10052
|
+
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
10053
|
+
}
|
|
10054
|
+
}
|
|
10055
|
+
|
|
9669
10056
|
module.exports = app => app.component('tasks', {
|
|
9670
10057
|
data: () => ({
|
|
9671
10058
|
status: 'init',
|
|
@@ -9693,10 +10080,22 @@ module.exports = app => app.component('tasks', {
|
|
|
9693
10080
|
scheduledAt: '',
|
|
9694
10081
|
parameters: '',
|
|
9695
10082
|
repeatInterval: ''
|
|
9696
|
-
}
|
|
10083
|
+
},
|
|
10084
|
+
// Chart over time
|
|
10085
|
+
overTimeChart: null,
|
|
10086
|
+
overTimeBuckets: [],
|
|
10087
|
+
// Toggled with v-if on the canvas so Chart.js is torn down and remounted on
|
|
10088
|
+
// filter changes. Updating Chart.js in place during a big Vue re-render was
|
|
10089
|
+
// freezing the page (dropdowns unresponsive, chart stale).
|
|
10090
|
+
showOverTimeChart: true
|
|
9697
10091
|
}),
|
|
9698
10092
|
methods: {
|
|
9699
10093
|
async getTasks() {
|
|
10094
|
+
// Hide chart canvas + teardown Chart.js immediately on filter changes
|
|
10095
|
+
// (see showOverTimeChart + v-if on the canvas in tasks.html).
|
|
10096
|
+
this.showOverTimeChart = false;
|
|
10097
|
+
this.destroyOverTimeChart();
|
|
10098
|
+
|
|
9700
10099
|
const params = {};
|
|
9701
10100
|
if (this.selectedStatus == 'all') {
|
|
9702
10101
|
params.status = null;
|
|
@@ -9715,9 +10114,105 @@ module.exports = app => app.component('tasks', {
|
|
|
9715
10114
|
params.name = this.searchQuery.trim();
|
|
9716
10115
|
}
|
|
9717
10116
|
|
|
9718
|
-
const
|
|
9719
|
-
|
|
9720
|
-
|
|
10117
|
+
const [overviewResult, overTimeResult] = await Promise.all([
|
|
10118
|
+
api.Task.getTaskOverview(params),
|
|
10119
|
+
api.Task.getTasksOverTime({
|
|
10120
|
+
start: params.start,
|
|
10121
|
+
end: params.end,
|
|
10122
|
+
bucketSizeMs: getBucketSizeMs(this.selectedRange)
|
|
10123
|
+
})
|
|
10124
|
+
]);
|
|
10125
|
+
|
|
10126
|
+
this.statusCounts = overviewResult.statusCounts || this.statusCounts;
|
|
10127
|
+
this.tasksByName = overviewResult.tasksByName || [];
|
|
10128
|
+
this.overTimeBuckets = overTimeResult || [];
|
|
10129
|
+
if (this.overTimeBuckets.length === 0) {
|
|
10130
|
+
this.showOverTimeChart = false;
|
|
10131
|
+
this.destroyOverTimeChart();
|
|
10132
|
+
} else {
|
|
10133
|
+
this.showOverTimeChart = true;
|
|
10134
|
+
await this.$nextTick();
|
|
10135
|
+
this.renderOverTimeChart();
|
|
10136
|
+
}
|
|
10137
|
+
},
|
|
10138
|
+
|
|
10139
|
+
/** Build or update the stacked bar chart showing tasks over time. */
|
|
10140
|
+
renderOverTimeChart() {
|
|
10141
|
+
const Chart = typeof window !== 'undefined' && window.Chart;
|
|
10142
|
+
if (!Chart) {
|
|
10143
|
+
throw new Error('Chart.js not found');
|
|
10144
|
+
}
|
|
10145
|
+
const canvas = this.$refs.overTimeChart;
|
|
10146
|
+
if (!canvas || typeof canvas.getContext !== 'function') return;
|
|
10147
|
+
|
|
10148
|
+
const buckets = this.overTimeBuckets;
|
|
10149
|
+
const labels = buckets.map(b => formatBucketLabel(b.timestamp, this.selectedRange));
|
|
10150
|
+
const succeeded = buckets.map(b => b.succeeded || 0);
|
|
10151
|
+
const failed = buckets.map(b => b.failed || 0);
|
|
10152
|
+
const cancelled = buckets.map(b => b.cancelled || 0);
|
|
10153
|
+
|
|
10154
|
+
const isDark = typeof document !== 'undefined' && document.documentElement.classList.contains('dark');
|
|
10155
|
+
const tickColor = isDark ? 'rgba(255,255,255,0.7)' : 'rgba(0,0,0,0.6)';
|
|
10156
|
+
const gridColor = isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)';
|
|
10157
|
+
|
|
10158
|
+
const chartData = {
|
|
10159
|
+
labels,
|
|
10160
|
+
datasets: [
|
|
10161
|
+
{ label: 'Succeeded', data: succeeded, backgroundColor: '#22c55e', stack: 'tasks' },
|
|
10162
|
+
{ label: 'Failed', data: failed, backgroundColor: '#ef4444', stack: 'tasks' },
|
|
10163
|
+
{ label: 'Cancelled', data: cancelled, backgroundColor: '#6b7280', stack: 'tasks' }
|
|
10164
|
+
]
|
|
10165
|
+
};
|
|
10166
|
+
|
|
10167
|
+
if (this.overTimeChart) {
|
|
10168
|
+
try {
|
|
10169
|
+
this.overTimeChart.data.labels = labels;
|
|
10170
|
+
this.overTimeChart.data.datasets[0].data = succeeded;
|
|
10171
|
+
this.overTimeChart.data.datasets[1].data = failed;
|
|
10172
|
+
this.overTimeChart.data.datasets[2].data = cancelled;
|
|
10173
|
+
this.overTimeChart.update('none');
|
|
10174
|
+
} finally {
|
|
10175
|
+
this.destroyOverTimeChart();
|
|
10176
|
+
}
|
|
10177
|
+
}
|
|
10178
|
+
|
|
10179
|
+
this.overTimeChart = new Chart(canvas, {
|
|
10180
|
+
type: 'bar',
|
|
10181
|
+
data: chartData,
|
|
10182
|
+
options: {
|
|
10183
|
+
responsive: true,
|
|
10184
|
+
maintainAspectRatio: false,
|
|
10185
|
+
animation: false,
|
|
10186
|
+
scales: {
|
|
10187
|
+
x: {
|
|
10188
|
+
stacked: true,
|
|
10189
|
+
ticks: { color: tickColor, maxRotation: 45, minRotation: 0 },
|
|
10190
|
+
grid: { color: gridColor }
|
|
10191
|
+
},
|
|
10192
|
+
y: {
|
|
10193
|
+
stacked: true,
|
|
10194
|
+
beginAtZero: true,
|
|
10195
|
+
ticks: { color: tickColor, precision: 0 },
|
|
10196
|
+
grid: { color: gridColor }
|
|
10197
|
+
}
|
|
10198
|
+
},
|
|
10199
|
+
plugins: {
|
|
10200
|
+
legend: {
|
|
10201
|
+
display: true,
|
|
10202
|
+
position: 'top',
|
|
10203
|
+
labels: { color: tickColor }
|
|
10204
|
+
},
|
|
10205
|
+
tooltip: { mode: 'index', intersect: false }
|
|
10206
|
+
}
|
|
10207
|
+
}
|
|
10208
|
+
});
|
|
10209
|
+
},
|
|
10210
|
+
|
|
10211
|
+
destroyOverTimeChart() {
|
|
10212
|
+
if (this.overTimeChart) {
|
|
10213
|
+
this.overTimeChart.destroy();
|
|
10214
|
+
this.overTimeChart = null;
|
|
10215
|
+
}
|
|
9721
10216
|
},
|
|
9722
10217
|
openTaskGroupDetails(group) {
|
|
9723
10218
|
const query = { dateRange: this.selectedRange || 'last_hour' };
|
|
@@ -9893,11 +10388,23 @@ module.exports = app => app.component('tasks', {
|
|
|
9893
10388
|
}
|
|
9894
10389
|
},
|
|
9895
10390
|
mounted: async function() {
|
|
10391
|
+
// Load initial data while showing the loader state.
|
|
9896
10392
|
await this.updateDateRange();
|
|
9897
|
-
|
|
10393
|
+
|
|
10394
|
+
// Once data is loaded, switch to the main view.
|
|
9898
10395
|
this.status = 'loaded';
|
|
10396
|
+
await this.$nextTick();
|
|
10397
|
+
|
|
10398
|
+
// Ensure the chart renders now that the canvas exists in the DOM.
|
|
10399
|
+
if (this.showOverTimeChart && this.overTimeBuckets.length > 0) {
|
|
10400
|
+
this.renderOverTimeChart();
|
|
10401
|
+
}
|
|
10402
|
+
|
|
9899
10403
|
this.setDefaultCreateTaskValues();
|
|
9900
10404
|
},
|
|
10405
|
+
beforeUnmount() {
|
|
10406
|
+
this.destroyOverTimeChart();
|
|
10407
|
+
},
|
|
9901
10408
|
template: template
|
|
9902
10409
|
});
|
|
9903
10410
|
|
|
@@ -10200,9 +10707,15 @@ var map = {
|
|
|
10200
10707
|
"./detail-array/detail-array": "./frontend/src/detail-array/detail-array.js",
|
|
10201
10708
|
"./detail-array/detail-array.html": "./frontend/src/detail-array/detail-array.html",
|
|
10202
10709
|
"./detail-array/detail-array.js": "./frontend/src/detail-array/detail-array.js",
|
|
10710
|
+
"./detail-date/detail-date": "./frontend/src/detail-date/detail-date.js",
|
|
10711
|
+
"./detail-date/detail-date.html": "./frontend/src/detail-date/detail-date.html",
|
|
10712
|
+
"./detail-date/detail-date.js": "./frontend/src/detail-date/detail-date.js",
|
|
10203
10713
|
"./detail-default/detail-default": "./frontend/src/detail-default/detail-default.js",
|
|
10204
10714
|
"./detail-default/detail-default.html": "./frontend/src/detail-default/detail-default.html",
|
|
10205
10715
|
"./detail-default/detail-default.js": "./frontend/src/detail-default/detail-default.js",
|
|
10716
|
+
"./document-details/date-view-mode-picker/date-view-mode-picker": "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.js",
|
|
10717
|
+
"./document-details/date-view-mode-picker/date-view-mode-picker.html": "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.html",
|
|
10718
|
+
"./document-details/date-view-mode-picker/date-view-mode-picker.js": "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.js",
|
|
10206
10719
|
"./document-details/document-details": "./frontend/src/document-details/document-details.js",
|
|
10207
10720
|
"./document-details/document-details.css": "./frontend/src/document-details/document-details.css",
|
|
10208
10721
|
"./document-details/document-details.html": "./frontend/src/document-details/document-details.html",
|
|
@@ -10252,6 +10765,8 @@ var map = {
|
|
|
10252
10765
|
"./export-query-results/export-query-results.js": "./frontend/src/export-query-results/export-query-results.js",
|
|
10253
10766
|
"./format": "./frontend/src/format.js",
|
|
10254
10767
|
"./format.js": "./frontend/src/format.js",
|
|
10768
|
+
"./getCurrentDateTimeContext": "./frontend/src/getCurrentDateTimeContext.js",
|
|
10769
|
+
"./getCurrentDateTimeContext.js": "./frontend/src/getCurrentDateTimeContext.js",
|
|
10255
10770
|
"./index": "./frontend/src/index.js",
|
|
10256
10771
|
"./index.js": "./frontend/src/index.js",
|
|
10257
10772
|
"./json-node/json-node": "./frontend/src/json-node/json-node.js",
|
|
@@ -10302,6 +10817,9 @@ var map = {
|
|
|
10302
10817
|
"./navbar/navbar.css": "./frontend/src/navbar/navbar.css",
|
|
10303
10818
|
"./navbar/navbar.html": "./frontend/src/navbar/navbar.html",
|
|
10304
10819
|
"./navbar/navbar.js": "./frontend/src/navbar/navbar.js",
|
|
10820
|
+
"./pro-upgrade-modal/pro-upgrade-modal": "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.js",
|
|
10821
|
+
"./pro-upgrade-modal/pro-upgrade-modal.html": "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.html",
|
|
10822
|
+
"./pro-upgrade-modal/pro-upgrade-modal.js": "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.js",
|
|
10305
10823
|
"./routes": "./frontend/src/routes.js",
|
|
10306
10824
|
"./routes.js": "./frontend/src/routes.js",
|
|
10307
10825
|
"./splash/splash": "./frontend/src/splash/splash.js",
|
|
@@ -10416,7 +10934,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
10416
10934
|
/* harmony export */ });
|
|
10417
10935
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
10418
10936
|
/**
|
|
10419
|
-
* @vue/reactivity v3.5.
|
|
10937
|
+
* @vue/reactivity v3.5.32
|
|
10420
10938
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
10421
10939
|
* @license MIT
|
|
10422
10940
|
**/
|
|
@@ -12563,7 +13081,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
12563
13081
|
/* harmony import */ var _vue_reactivity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/reactivity */ "./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js");
|
|
12564
13082
|
/* harmony import */ var _vue_shared__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
12565
13083
|
/**
|
|
12566
|
-
* @vue/runtime-core v3.5.
|
|
13084
|
+
* @vue/runtime-core v3.5.32
|
|
12567
13085
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
12568
13086
|
* @license MIT
|
|
12569
13087
|
**/
|
|
@@ -13510,6 +14028,7 @@ function createPathGetter(ctx, path) {
|
|
|
13510
14028
|
};
|
|
13511
14029
|
}
|
|
13512
14030
|
|
|
14031
|
+
const pendingMounts = /* @__PURE__ */ new WeakMap();
|
|
13513
14032
|
const TeleportEndKey = /* @__PURE__ */ Symbol("_vte");
|
|
13514
14033
|
const isTeleport = (type) => type.__isTeleport;
|
|
13515
14034
|
const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === "");
|
|
@@ -13551,91 +14070,86 @@ const TeleportImpl = {
|
|
|
13551
14070
|
o: { insert, querySelector, createText, createComment }
|
|
13552
14071
|
} = internals;
|
|
13553
14072
|
const disabled = isTeleportDisabled(n2.props);
|
|
13554
|
-
let {
|
|
14073
|
+
let { dynamicChildren } = n2;
|
|
13555
14074
|
if ( true && isHmrUpdating) {
|
|
13556
14075
|
optimized = false;
|
|
13557
14076
|
dynamicChildren = null;
|
|
13558
14077
|
}
|
|
14078
|
+
const mount = (vnode, container2, anchor2) => {
|
|
14079
|
+
if (vnode.shapeFlag & 16) {
|
|
14080
|
+
mountChildren(
|
|
14081
|
+
vnode.children,
|
|
14082
|
+
container2,
|
|
14083
|
+
anchor2,
|
|
14084
|
+
parentComponent,
|
|
14085
|
+
parentSuspense,
|
|
14086
|
+
namespace,
|
|
14087
|
+
slotScopeIds,
|
|
14088
|
+
optimized
|
|
14089
|
+
);
|
|
14090
|
+
}
|
|
14091
|
+
};
|
|
14092
|
+
const mountToTarget = (vnode = n2) => {
|
|
14093
|
+
const disabled2 = isTeleportDisabled(vnode.props);
|
|
14094
|
+
const target = vnode.target = resolveTarget(vnode.props, querySelector);
|
|
14095
|
+
const targetAnchor = prepareAnchor(target, vnode, createText, insert);
|
|
14096
|
+
if (target) {
|
|
14097
|
+
if (namespace !== "svg" && isTargetSVG(target)) {
|
|
14098
|
+
namespace = "svg";
|
|
14099
|
+
} else if (namespace !== "mathml" && isTargetMathML(target)) {
|
|
14100
|
+
namespace = "mathml";
|
|
14101
|
+
}
|
|
14102
|
+
if (parentComponent && parentComponent.isCE) {
|
|
14103
|
+
(parentComponent.ce._teleportTargets || (parentComponent.ce._teleportTargets = /* @__PURE__ */ new Set())).add(target);
|
|
14104
|
+
}
|
|
14105
|
+
if (!disabled2) {
|
|
14106
|
+
mount(vnode, target, targetAnchor);
|
|
14107
|
+
updateCssVars(vnode, false);
|
|
14108
|
+
}
|
|
14109
|
+
} else if ( true && !disabled2) {
|
|
14110
|
+
warn$1("Invalid Teleport target on mount:", target, `(${typeof target})`);
|
|
14111
|
+
}
|
|
14112
|
+
};
|
|
14113
|
+
const queuePendingMount = (vnode) => {
|
|
14114
|
+
const mountJob = () => {
|
|
14115
|
+
if (pendingMounts.get(vnode) !== mountJob) return;
|
|
14116
|
+
pendingMounts.delete(vnode);
|
|
14117
|
+
if (isTeleportDisabled(vnode.props)) {
|
|
14118
|
+
mount(vnode, container, vnode.anchor);
|
|
14119
|
+
updateCssVars(vnode, true);
|
|
14120
|
+
}
|
|
14121
|
+
mountToTarget(vnode);
|
|
14122
|
+
};
|
|
14123
|
+
pendingMounts.set(vnode, mountJob);
|
|
14124
|
+
queuePostRenderEffect(mountJob, parentSuspense);
|
|
14125
|
+
};
|
|
13559
14126
|
if (n1 == null) {
|
|
13560
14127
|
const placeholder = n2.el = true ? createComment("teleport start") : 0;
|
|
13561
14128
|
const mainAnchor = n2.anchor = true ? createComment("teleport end") : 0;
|
|
13562
14129
|
insert(placeholder, container, anchor);
|
|
13563
14130
|
insert(mainAnchor, container, anchor);
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
container2,
|
|
13569
|
-
anchor2,
|
|
13570
|
-
parentComponent,
|
|
13571
|
-
parentSuspense,
|
|
13572
|
-
namespace,
|
|
13573
|
-
slotScopeIds,
|
|
13574
|
-
optimized
|
|
13575
|
-
);
|
|
13576
|
-
}
|
|
13577
|
-
};
|
|
13578
|
-
const mountToTarget = () => {
|
|
13579
|
-
const target = n2.target = resolveTarget(n2.props, querySelector);
|
|
13580
|
-
const targetAnchor = prepareAnchor(target, n2, createText, insert);
|
|
13581
|
-
if (target) {
|
|
13582
|
-
if (namespace !== "svg" && isTargetSVG(target)) {
|
|
13583
|
-
namespace = "svg";
|
|
13584
|
-
} else if (namespace !== "mathml" && isTargetMathML(target)) {
|
|
13585
|
-
namespace = "mathml";
|
|
13586
|
-
}
|
|
13587
|
-
if (parentComponent && parentComponent.isCE) {
|
|
13588
|
-
(parentComponent.ce._teleportTargets || (parentComponent.ce._teleportTargets = /* @__PURE__ */ new Set())).add(target);
|
|
13589
|
-
}
|
|
13590
|
-
if (!disabled) {
|
|
13591
|
-
mount(target, targetAnchor);
|
|
13592
|
-
updateCssVars(n2, false);
|
|
13593
|
-
}
|
|
13594
|
-
} else if ( true && !disabled) {
|
|
13595
|
-
warn$1(
|
|
13596
|
-
"Invalid Teleport target on mount:",
|
|
13597
|
-
target,
|
|
13598
|
-
`(${typeof target})`
|
|
13599
|
-
);
|
|
13600
|
-
}
|
|
13601
|
-
};
|
|
14131
|
+
if (isTeleportDeferred(n2.props) || parentSuspense && parentSuspense.pendingBranch) {
|
|
14132
|
+
queuePendingMount(n2);
|
|
14133
|
+
return;
|
|
14134
|
+
}
|
|
13602
14135
|
if (disabled) {
|
|
13603
|
-
mount(container, mainAnchor);
|
|
14136
|
+
mount(n2, container, mainAnchor);
|
|
13604
14137
|
updateCssVars(n2, true);
|
|
13605
14138
|
}
|
|
13606
|
-
|
|
13607
|
-
n2.el.__isMounted = false;
|
|
13608
|
-
queuePostRenderEffect(() => {
|
|
13609
|
-
if (n2.el.__isMounted !== false) return;
|
|
13610
|
-
mountToTarget();
|
|
13611
|
-
delete n2.el.__isMounted;
|
|
13612
|
-
}, parentSuspense);
|
|
13613
|
-
} else {
|
|
13614
|
-
mountToTarget();
|
|
13615
|
-
}
|
|
14139
|
+
mountToTarget();
|
|
13616
14140
|
} else {
|
|
13617
14141
|
n2.el = n1.el;
|
|
13618
|
-
n2.targetStart = n1.targetStart;
|
|
13619
14142
|
const mainAnchor = n2.anchor = n1.anchor;
|
|
13620
|
-
const
|
|
13621
|
-
|
|
13622
|
-
|
|
13623
|
-
|
|
13624
|
-
|
|
13625
|
-
n1,
|
|
13626
|
-
n2,
|
|
13627
|
-
container,
|
|
13628
|
-
anchor,
|
|
13629
|
-
parentComponent,
|
|
13630
|
-
parentSuspense,
|
|
13631
|
-
namespace,
|
|
13632
|
-
slotScopeIds,
|
|
13633
|
-
optimized,
|
|
13634
|
-
internals
|
|
13635
|
-
);
|
|
13636
|
-
}, parentSuspense);
|
|
14143
|
+
const pendingMount = pendingMounts.get(n1);
|
|
14144
|
+
if (pendingMount) {
|
|
14145
|
+
pendingMount.flags |= 8;
|
|
14146
|
+
pendingMounts.delete(n1);
|
|
14147
|
+
queuePendingMount(n2);
|
|
13637
14148
|
return;
|
|
13638
14149
|
}
|
|
14150
|
+
n2.targetStart = n1.targetStart;
|
|
14151
|
+
const target = n2.target = n1.target;
|
|
14152
|
+
const targetAnchor = n2.targetAnchor = n1.targetAnchor;
|
|
13639
14153
|
const wasDisabled = isTeleportDisabled(n1.props);
|
|
13640
14154
|
const currentContainer = wasDisabled ? container : target;
|
|
13641
14155
|
const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;
|
|
@@ -13726,13 +14240,19 @@ const TeleportImpl = {
|
|
|
13726
14240
|
target,
|
|
13727
14241
|
props
|
|
13728
14242
|
} = vnode;
|
|
14243
|
+
let shouldRemove = doRemove || !isTeleportDisabled(props);
|
|
14244
|
+
const pendingMount = pendingMounts.get(vnode);
|
|
14245
|
+
if (pendingMount) {
|
|
14246
|
+
pendingMount.flags |= 8;
|
|
14247
|
+
pendingMounts.delete(vnode);
|
|
14248
|
+
shouldRemove = false;
|
|
14249
|
+
}
|
|
13729
14250
|
if (target) {
|
|
13730
14251
|
hostRemove(targetStart);
|
|
13731
14252
|
hostRemove(targetAnchor);
|
|
13732
14253
|
}
|
|
13733
14254
|
doRemove && hostRemove(anchor);
|
|
13734
14255
|
if (shapeFlag & 16) {
|
|
13735
|
-
const shouldRemove = doRemove || !isTeleportDisabled(props);
|
|
13736
14256
|
for (let i = 0; i < children.length; i++) {
|
|
13737
14257
|
const child = children[i];
|
|
13738
14258
|
unmount(
|
|
@@ -19941,6 +20461,7 @@ function createSuspenseBoundary(vnode, parentSuspense, parentComponent, containe
|
|
|
19941
20461
|
if (instance.isUnmounted || suspense.isUnmounted || suspense.pendingId !== instance.suspenseId) {
|
|
19942
20462
|
return;
|
|
19943
20463
|
}
|
|
20464
|
+
unsetCurrentInstance();
|
|
19944
20465
|
instance.asyncResolved = true;
|
|
19945
20466
|
const { vnode: vnode2 } = instance;
|
|
19946
20467
|
if (true) {
|
|
@@ -21147,7 +21668,7 @@ function isMemoSame(cached, memo) {
|
|
|
21147
21668
|
return true;
|
|
21148
21669
|
}
|
|
21149
21670
|
|
|
21150
|
-
const version = "3.5.
|
|
21671
|
+
const version = "3.5.32";
|
|
21151
21672
|
const warn = true ? warn$1 : 0;
|
|
21152
21673
|
const ErrorTypeStrings = ErrorTypeStrings$1 ;
|
|
21153
21674
|
const devtools = true ? devtools$1 : 0;
|
|
@@ -21358,7 +21879,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
21358
21879
|
/* harmony import */ var _vue_runtime_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/runtime-core */ "./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js");
|
|
21359
21880
|
/* harmony import */ var _vue_runtime_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @vue/shared */ "./node_modules/@vue/shared/dist/shared.esm-bundler.js");
|
|
21360
21881
|
/**
|
|
21361
|
-
* @vue/runtime-dom v3.5.
|
|
21882
|
+
* @vue/runtime-dom v3.5.32
|
|
21362
21883
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
21363
21884
|
* @license MIT
|
|
21364
21885
|
**/
|
|
@@ -23430,7 +23951,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
23430
23951
|
/* harmony export */ toTypeString: () => (/* binding */ toTypeString)
|
|
23431
23952
|
/* harmony export */ });
|
|
23432
23953
|
/**
|
|
23433
|
-
* @vue/shared v3.5.
|
|
23954
|
+
* @vue/shared v3.5.32
|
|
23434
23955
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
23435
23956
|
* @license MIT
|
|
23436
23957
|
**/
|
|
@@ -48767,6 +49288,151 @@ module.exports = function stringToParts(str) {
|
|
|
48767
49288
|
|
|
48768
49289
|
!function(t,e){ true?module.exports=e():0}(this,()=>(()=>{"use strict";var t={242(t,e,n){const r=n(714),{ArrayPrototypeMap:o}=r;e.h=class{hexSlice(t=0,e){return o(this.slice(t,e),t=>("00"+t.toString(16)).slice(-2)).join("")}}},702(t,e,n){const r=n(714),{AggregateError:o,AggregateErrorPrototype:i,Array:s,ArrayBuffer:l,ArrayBufferPrototype:c,ArrayIsArray:a,ArrayPrototype:u,ArrayPrototypeFilter:f,ArrayPrototypeForEach:p,ArrayPrototypeIncludes:y,ArrayPrototypeIndexOf:g,ArrayPrototypeJoin:h,ArrayPrototypeMap:d,ArrayPrototypePop:m,ArrayPrototypePush:b,ArrayPrototypePushApply:$,ArrayPrototypeSlice:S,ArrayPrototypeSort:x,ArrayPrototypeSplice:P,ArrayPrototypeUnshift:A,BigIntPrototypeValueOf:v,Boolean:_,BooleanPrototype:w,BooleanPrototypeValueOf:E,DataView:O,DataViewPrototype:L,Date:R,DatePrototype:k,DatePrototypeGetTime:I,DatePrototypeToISOString:j,DatePrototypeToString:B,Error:T,ErrorPrototype:z,ErrorPrototypeToString:M,Function:N,FunctionPrototype:C,FunctionPrototypeBind:F,FunctionPrototypeCall:D,FunctionPrototypeSymbolHasInstance:W,FunctionPrototypeToString:H,JSONStringify:U,Map:G,MapPrototype:V,MapPrototypeEntries:Z,MapPrototypeGetSize:Y,MathFloor:q,MathMax:J,MathMin:K,MathRound:Q,MathSqrt:X,MathTrunc:tt,Number:et,NumberIsFinite:nt,NumberIsNaN:rt,NumberParseFloat:ot,NumberParseInt:it,NumberPrototype:st,NumberPrototypeToString:lt,NumberPrototypeValueOf:ct,Object:at,ObjectAssign:ut,ObjectDefineProperty:ft,ObjectGetOwnPropertyDescriptor:pt,ObjectGetOwnPropertyNames:yt,ObjectGetOwnPropertySymbols:gt,ObjectGetPrototypeOf:ht,ObjectIs:dt,ObjectKeys:mt,ObjectPrototype:bt,ObjectPrototypeHasOwnProperty:$t,ObjectPrototypePropertyIsEnumerable:St,ObjectPrototypeToString:xt,ObjectSeal:Pt,ObjectSetPrototypeOf:At,Promise:vt,PromisePrototype:_t,RangeError:wt,RangeErrorPrototype:Et,ReflectApply:Ot,ReflectOwnKeys:Lt,RegExp:Rt,RegExpPrototype:kt,RegExpPrototypeExec:It,RegExpPrototypeSymbolReplace:jt,RegExpPrototypeSymbolSplit:Bt,RegExpPrototypeToString:Tt,SafeMap:zt,SafeSet:Mt,SafeStringIterator:Nt,Set:Ct,SetPrototype:Ft,SetPrototypeGetSize:Dt,SetPrototypeValues:Wt,String:Ht,StringPrototype:Ut,StringPrototypeCharCodeAt:Gt,StringPrototypeCodePointAt:Vt,StringPrototypeEndsWith:Zt,StringPrototypeIncludes:Yt,StringPrototypeIndexOf:qt,StringPrototypeLastIndexOf:Jt,StringPrototypeNormalize:Kt,StringPrototypePadEnd:Qt,StringPrototypePadStart:Xt,StringPrototypeRepeat:te,StringPrototypeReplace:ee,StringPrototypeReplaceAll:ne,StringPrototypeSlice:re,StringPrototypeSplit:oe,StringPrototypeStartsWith:ie,StringPrototypeToLowerCase:se,StringPrototypeValueOf:le,SymbolIterator:ce,SymbolPrototypeToString:ae,SymbolPrototypeValueOf:ue,SymbolToPrimitive:fe,SymbolToStringTag:pe,TypeError:ye,TypeErrorPrototype:ge,TypedArray:he,TypedArrayPrototype:de,TypedArrayPrototypeGetLength:me,TypedArrayPrototypeGetSymbolToStringTag:be,Uint8Array:$e,WeakMap:Se,WeakMapPrototype:xe,WeakSet:Pe,WeakSetPrototype:Ae,globalThis:ve,internalBinding:_e,uncurryThis:we}=r,{constants:{ALL_PROPERTIES:Ee,ONLY_ENUMERABLE:Oe,kPending:Le,kRejected:Re},getOwnNonIndexProperties:ke,getPromiseDetails:Ie,getProxyDetails:je,previewEntries:Be,getConstructorName:Te,getExternalValue:ze,Proxy:Me}=n(596),{customInspectSymbol:Ne,isError:Ce,join:Fe,removeColors:De}=n(992),{isStackOverflowError:We}=n(923),{isAsyncFunction:He,isGeneratorFunction:Ue,isAnyArrayBuffer:Ge,isArrayBuffer:Ve,isArgumentsObject:Ze,isBoxedPrimitive:Ye,isDataView:qe,isExternal:Je,isMap:Ke,isMapIterator:Qe,isModuleNamespaceObject:Xe,isNativeError:tn,isPromise:en,isSet:nn,isSetIterator:rn,isWeakMap:on,isWeakSet:sn,isRegExp:ln,isDate:cn,isTypedArray:an,isStringObject:un,isNumberObject:fn,isBooleanObject:pn,isBigIntObject:yn}=n(134),gn=n(146),{BuiltinModule:hn}=n(996),{validateObject:dn,validateString:mn,kValidateObjectAllowArray:bn}=n(63);let $n,Sn,xn;function Pn(t){return Sn=Sn||n(511),Sn.pathToFileURL(t).href}const An=new Mt(f(yt(ve),t=>null!==It(/^[A-Z][a-zA-Z0-9]+$/,t))),vn=t=>void 0===t&&void 0!==t,_n=Pt({showHidden:!1,depth:2,colors:!1,customInspect:!0,showProxy:!1,maxArrayLength:100,maxStringLength:1e4,breakLength:80,compact:3,sorted:!1,getters:!1,numericSeparator:!1}),wn=/[\x00-\x1f\x27\x5c\x7f-\x9f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/,En=/[\x00-\x1f\x27\x5c\x7f-\x9f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g,On=/[\x00-\x1f\x5c\x7f-\x9f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/,Ln=/[\x00-\x1f\x5c\x7f-\x9f]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g,Rn=/^[a-zA-Z_][a-zA-Z_0-9]*$/,kn=/^(0|[1-9][0-9]*)$/,In=/^ {4}at (?:[^/\\(]+ \(|)node:(.+):\d+:\d+\)?$/,jn=/^(\s+[^(]*?)\s*{/,Bn=/(\/\/.*?\n)|(\/\*(.|\n)*?\*\/)/g,Tn=["\\x00","\\x01","\\x02","\\x03","\\x04","\\x05","\\x06","\\x07","\\b","\\t","\\n","\\x0B","\\f","\\r","\\x0E","\\x0F","\\x10","\\x11","\\x12","\\x13","\\x14","\\x15","\\x16","\\x17","\\x18","\\x19","\\x1A","\\x1B","\\x1C","\\x1D","\\x1E","\\x1F","","","","","","","","\\'","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\\\\","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","\\x7F","\\x80","\\x81","\\x82","\\x83","\\x84","\\x85","\\x86","\\x87","\\x88","\\x89","\\x8A","\\x8B","\\x8C","\\x8D","\\x8E","\\x8F","\\x90","\\x91","\\x92","\\x93","\\x94","\\x95","\\x96","\\x97","\\x98","\\x99","\\x9A","\\x9B","\\x9C","\\x9D","\\x9E","\\x9F"],zn=new Rt("[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/\\#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))","g");let Mn;function Nn(t,e){const n={budget:{},indentationLvl:0,seen:[],currentDepth:0,stylize:Zn,showHidden:_n.showHidden,depth:_n.depth,colors:_n.colors,customInspect:_n.customInspect,showProxy:_n.showProxy,maxArrayLength:_n.maxArrayLength,maxStringLength:_n.maxStringLength,breakLength:_n.breakLength,compact:_n.compact,sorted:_n.sorted,getters:_n.getters,numericSeparator:_n.numericSeparator};if(arguments.length>1)if(arguments.length>2&&(void 0!==arguments[2]&&(n.depth=arguments[2]),arguments.length>3&&void 0!==arguments[3]&&(n.colors=arguments[3])),"boolean"==typeof e)n.showHidden=e;else if(e){const t=mt(e);for(let r=0;r<t.length;++r){const o=t[r];$t(_n,o)||"stylize"===o?n[o]=e[o]:void 0===n.userOptions&&(n.userOptions=e)}}return n.colors&&(n.stylize=Vn),null===n.maxArrayLength&&(n.maxArrayLength=1/0),null===n.maxStringLength&&(n.maxStringLength=1/0),nr(n,t,0)}Nn.custom=Ne,ft(Nn,"defaultOptions",{__proto__:null,get:()=>_n,set:t=>(dn(t,"options"),ut(_n,t))});const Cn=39,Fn=49;function Dn(t,e){ft(Nn.colors,e,{__proto__:null,get(){return this[t]},set(e){this[t]=e},configurable:!0,enumerable:!1})}Nn.colors={__proto__:null,reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],blink:[5,25],inverse:[7,27],hidden:[8,28],strikethrough:[9,29],doubleunderline:[21,24],black:[30,Cn],red:[31,Cn],green:[32,Cn],yellow:[33,Cn],blue:[34,Cn],magenta:[35,Cn],cyan:[36,Cn],white:[37,Cn],bgBlack:[40,Fn],bgRed:[41,Fn],bgGreen:[42,Fn],bgYellow:[43,Fn],bgBlue:[44,Fn],bgMagenta:[45,Fn],bgCyan:[46,Fn],bgWhite:[47,Fn],framed:[51,54],overlined:[53,55],gray:[90,Cn],redBright:[91,Cn],greenBright:[92,Cn],yellowBright:[93,Cn],blueBright:[94,Cn],magentaBright:[95,Cn],cyanBright:[96,Cn],whiteBright:[97,Cn],bgGray:[100,Fn],bgRedBright:[101,Fn],bgGreenBright:[102,Fn],bgYellowBright:[103,Fn],bgBlueBright:[104,Fn],bgMagentaBright:[105,Fn],bgCyanBright:[106,Fn],bgWhiteBright:[107,Fn]},Dn("gray","grey"),Dn("gray","blackBright"),Dn("bgGray","bgGrey"),Dn("bgGray","bgBlackBright"),Dn("dim","faint"),Dn("strikethrough","crossedout"),Dn("strikethrough","strikeThrough"),Dn("strikethrough","crossedOut"),Dn("hidden","conceal"),Dn("inverse","swapColors"),Dn("inverse","swapcolors"),Dn("doubleunderline","doubleUnderline"),Nn.styles=ut({__proto__:null},{special:"cyan",number:"yellow",bigint:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",symbol:"green",date:"magenta",regexp:function t(e){let n="",r=0,o=0,i=!1;const s=(t.colors?.length>0?t.colors:Wn).reduce((t,e)=>{const n=Nn.colors[e];return n&&t.push([`[${n[0]}m`,`[${n[1]}m`]),t},[]);function l(t,n,i=1){let s="";for(r++;r<e.length&&e[r]!==n;)s+=e[r++];r<e.length?(o-=i,c(t),a(s,1,1),c(n),o+=i):a(t,1,-s.length)}const c=t=>{const e=o%s.length,r=s[e]??s[0];return n+=r[0]+t+r[1],e};function a(t,e,n){o+=e,c(t),o-=e,r+=n}for(c("/"),o++,r=1;r<e.length;){const t=e[r];if(i)if("\\"===t){let t="\\";if(r++,r<e.length){t+=e[r++];const n=t[1];if("u"===n&&"{"===e[r]){l(`${t}{`,"}",0);continue}if(("p"===n||"P"===n)&&"{"===e[r]){l(`${t}{`,"}",0);continue}"x"===t[1]&&(t+=e.slice(r,r+2),r+=2)}c(t)}else"]"===t?(o--,c("]"),r++,i=!1):"-"===t&&"["!==e[r-1]&&r+1<e.length&&"]"!==e[r+1]?a("-",1,1):(c(t),r++);else if("["===t)c("["),o++,r++,i=!0;else if("("===t){if(c("("),o++,r++,r<e.length&&"?"===e[r]){r++;const t=r<e.length?e[r]:"";if(":"===t||"="===t||"!"===t)a(`?${t}`,-1,1);else{const n=r+1<e.length?e[r+1]:"";if("<"!==t||"="!==n&&"!"!==n)if("<"===t){r++;const t=r;for(;r<e.length&&">"!==e[r];)r++;const n=e.slice(t,r);r<e.length&&">"===e[r]?(o--,c("?<"),a(n,1,0),c(">"),o++,r++):(a("?<",-1,0),c(n))}else c("?");else a(`?<${n}`,-1,2)}}}else if(")"===t)o--,c(")"),r++;else if("\\"===t){let t="\\";if(r++,r<e.length){t+=e[r++];const n=t[1];if(r<e.length){if("u"===n&&"{"===e[r]){l(`${t}{`,"}",0);continue}if("x"===n)t+=e.slice(r,r+2),r+=2;else if(n>="0"&&n<="9")for(;r<e.length&&e[r]>="0"&&e[r]<="9";)t+=e[r++];else{if("k"===n&&"<"===e[r]){l(`${t}<`,">");continue}if(("p"===n||"P"===n)&&"{"===e[r]){l(`${t}{`,"}",0);continue}}}}a(t,1,0)}else if("|"===t||"+"===t||"*"===t||"?"===t||","===t||"^"===t||"$"===t)a(t,3,1);else if("{"===t){r++;let t="";for(;r<e.length&&e[r]>="0"&&e[r]<="9";)t+=e[r++];if(t&&(c("{"),o++,a(t,1,0)),r<e.length)if(","===e[r])t||(c("{"),o++),c(","),r++;else if(!t){o+=1,c("{"),o-=1;continue}let n="";for(;r<e.length&&e[r]>="0"&&e[r]<="9";)n+=e[r++];n&&a(n,1,0),r<e.length&&"}"===e[r]&&(o--,c("}"),r++),r<e.length&&"?"===e[r]&&a("?",3,1)}else if("."===t)a(t,2,1);else{if("/"===t)break;a(t,1,1)}}return a("/",-1,1),r<e.length&&c(e.slice(r)),n},module:"underline"}),Nn.styles.regexp.colors=["green","red","yellow","cyan","magenta"];const Wn=Nn.styles.regexp.colors.slice();function Hn(t,e){return-1===e?`"${t}"`:-2===e?`\`${t}\``:`'${t}'`}function Un(t){const e=Gt(t);return Tn.length>e?Tn[e]:`\\u${lt(e,16)}`}function Gn(t){let e=wn,n=En,r=39;if(Yt(t,"'")&&(Yt(t,'"')?Yt(t,"`")||Yt(t,"${")||(r=-2):r=-1,39!==r&&(e=On,n=Ln)),t.length<5e3&&null===It(e,t))return Hn(t,r);if(t.length>100)return Hn(t=jt(n,t,Un),r);let o="",i=0;for(let e=0;e<t.length;e++){const n=Gt(t,e);if(n===r||92===n||n<32||n>126&&n<160)o+=i===e?Tn[n]:`${re(t,i,e)}${Tn[n]}`,i=e+1;else if(n>=55296&&n<=57343){if(n<=56319&&e+1<t.length){const n=Gt(t,e+1);if(n>=56320&&n<=57343){e++;continue}}o+=`${re(t,i,e)}\\u${lt(n,16)}`,i=e+1}}return i!==t.length&&(o+=re(t,i)),Hn(o,r)}function Vn(t,e){const n=Nn.styles[e];if(void 0!==n){const e=Nn.colors[n];if(void 0!==e)return`[${e[0]}m${t}[${e[1]}m`;if("function"==typeof n)return n(t)}return t}function Zn(t){return t}function Yn(){return[]}function qn(t,e){try{return t instanceof e}catch{return!1}}const Jn=(new zt).set(u,{name:"Array",constructor:s}).set(c,{name:"ArrayBuffer",constructor:l}).set(C,{name:"Function",constructor:N}).set(V,{name:"Map",constructor:G}).set(Ft,{name:"Set",constructor:Ct}).set(bt,{name:"Object",constructor:at}).set(de,{name:"TypedArray",constructor:he}).set(kt,{name:"RegExp",constructor:Rt}).set(k,{name:"Date",constructor:R}).set(L,{name:"DataView",constructor:O}).set(z,{name:"Error",constructor:T}).set(i,{name:"AggregateError",constructor:o}).set(Et,{name:"RangeError",constructor:wt}).set(ge,{name:"TypeError",constructor:ye}).set(w,{name:"Boolean",constructor:_}).set(st,{name:"Number",constructor:et}).set(Ut,{name:"String",constructor:Ht}).set(_t,{name:"Promise",constructor:vt}).set(xe,{name:"WeakMap",constructor:Se}).set(Ae,{name:"WeakSet",constructor:Pe});function Kn(t,e,n,r){let o;const i=t;for(;t||vn(t);){const s=Jn.get(t);if(void 0!==s){const{name:l,constructor:c}=s;if(W(c,i))return void 0!==r&&o!==t&&Qn(e,i,o||i,n,r),l}const l=pt(t,"constructor");if(void 0!==l&&"function"==typeof l.value&&""!==l.value.name&&qn(i,l.value))return void 0===r||o===t&&An.has(l.value.name)||Qn(e,i,o||i,n,r),Ht(l.value.name);t=ht(t),void 0===o&&(o=t)}if(null===o)return null;const s=Te(i);if(n>e.depth&&null!==e.depth)return`${s} <Complex prototype>`;const l=Kn(o,e,n+1,r);return null===l?`${s} <${Nn(o,{...e,customInspect:!1,depth:-1})}>`:`${s} <${l}>`}function Qn(t,e,n,r,o){let i,s,l=0;do{if(0!==l||e===n){if(null===(n=ht(n)))return;const t=pt(n,"constructor");if(void 0!==t&&"function"==typeof t.value&&An.has(t.value.name))return}0===l?s=new Mt:p(i,t=>s.add(t)),i=Lt(n),b(t.seen,e);for(const c of i){if("constructor"===c||$t(e,c)||0!==l&&s.has(c))continue;const i=pt(n,c);if("function"==typeof i.value)continue;const a=Or(t,n,r,c,0,i,e);t.colors?b(o,`[2m${a}[22m`):b(o,a)}m(t.seen)}while(3!==++l)}function Xn(t,e,n,r=""){if(null===t)return""!==e&&n!==e?`[${n}${r}: null prototype] [${e}] `:`[${n}${r}: null prototype] `;let o=`${t}${r} `;if(""!==e){const n=t.indexOf(e);if(-1===n)o+=`[${e}] `;else{const r=n+e.length;r!==t.length&&t[r]===t[r].toLowerCase()&&(o+=`[${e}] `)}}return o}function tr(t,e){let n;const r=gt(t);if(e)n=yt(t),0!==r.length&&$(n,r);else{try{n=mt(t)}catch(e){gn(tn(e)&&"ReferenceError"===e.name&&Xe(t)),n=yt(t)}0!==r.length&&$(n,f(r,e=>St(t,e)))}return n}function er(t,e,n){let r="";return null===e&&(r=Te(t),r===n&&(r="Object")),Xn(e,n,r)}function nr(t,e,o,i){if("object"!=typeof e&&"function"!=typeof e&&!vn(e))return pr(t.stylize,e,t);if(null===e)return t.stylize("null","null");const s=e,l=je(e,!!t.showProxy);if(void 0!==l){if(null===l||null===l[0])return t.stylize("<Revoked Proxy>","special");if(t.showProxy)return function(t,e,n){if(n>t.depth&&null!==t.depth)return t.stylize("Proxy [Array]","special");n+=1,t.indentationLvl+=2;const r=[nr(t,e[0],n),nr(t,e[1],n)];return t.indentationLvl-=2,Rr(t,r,"",["Proxy [","]"],2,n)}(t,l,o);e=l}if(t.customInspect){const n=e[Ne];if("function"==typeof n&&n!==Nn&&pt(e,"constructor")?.value?.prototype!==e){const e=null===t.depth?null:t.depth-o,r=void 0!==l||!W(at,s),i=D(n,s,e,function(t,e){const n={stylize:t.stylize,showHidden:t.showHidden,depth:t.depth,colors:t.colors,customInspect:t.customInspect,showProxy:t.showProxy,maxArrayLength:t.maxArrayLength,maxStringLength:t.maxStringLength,breakLength:t.breakLength,compact:t.compact,sorted:t.sorted,getters:t.getters,numericSeparator:t.numericSeparator,...t.userOptions};if(e){At(n,null);for(const t of mt(n))"object"!=typeof n[t]&&"function"!=typeof n[t]||null===n[t]||delete n[t];n.stylize=At((e,n)=>{let r;try{r=`${t.stylize(e,n)}`}catch{}return"string"!=typeof r?e:r},null)}return n}(t,r),Nn);if(i!==s)return"string"!=typeof i?nr(t,i,o):ne(i,"\n",`\n${te(" ",t.indentationLvl)}`)}}if(t.seen.includes(e)){let n=1;return void 0===t.circular?(t.circular=new zt,t.circular.set(e,n)):(n=t.circular.get(e),void 0===n&&(n=t.circular.size+1,t.circular.set(e,n))),t.stylize(`[Circular *${n}]`,"special")}return function(t,e,o,i){let s,l;t.showHidden&&(o<=t.depth||null===t.depth)&&(l=[]);const c=Kn(e,t,o,l);void 0!==l&&0===l.length&&(l=void 0);let u="";try{u=e[pe]}catch{}("string"!=typeof u||""!==u&&(t.showHidden?$t:St)(e,pe))&&(u="");let f,p,d="",m=Yn,_=!0;const w=t.showHidden?Ee:Oe;let O,L,R=0;if(ce in e||null===c)if(_=!1,a(e)){const t="Array"!==c||""!==u?Xn(c,u,"Array",`(${e.length})`):"";if(s=ke(e,w),f=[`${t}[`,"]"],0===e.length&&0===s.length&&void 0===l)return`${f[0]}]`;R=2,m=dr}else if(nn(e)){const n=Dt(e),r=Xn(c,u,"Set",`(${n})`);if(s=tr(e,t.showHidden),m=F(br,null,null!==c?e:Wt(e)),0===n&&0===s.length&&void 0===l)return`${r}{}`;f=[`${r}{`,"}"]}else if(Ke(e)){const n=Y(e),r=Xn(c,u,"Map",`(${n})`);if(s=tr(e,t.showHidden),m=F($r,null,null!==c?e:Z(e)),0===n&&0===s.length&&void 0===l)return`${r}{}`;f=[`${r}{`,"}"]}else if(an(e)){s=ke(e,w);let n=e,o="";null===c&&(o=be(e),n=new r[o](e));const l=me(e);if(f=[`${Xn(c,u,o,`(${l})`)}[`,"]"],0===e.length&&0===s.length&&!t.showHidden)return`${f[0]}]`;m=F(mr,null,n,l),R=2,t.showHidden&&(O=["BYTES_PER_ELEMENT","length","byteLength","byteOffset","buffer"],i=!0)}else Qe(e)?(s=tr(e,t.showHidden),f=rr("Map",u),m=F(_r,null,f)):rn(e)?(s=tr(e,t.showHidden),f=rr("Set",u),m=F(_r,null,f)):_=!0;if(_)if(s=tr(e,t.showHidden),f=["{","}"],"function"==typeof e){if(d=function(t,e,n,r){const o=H(e);if(ie(o,"class")&&"}"===o[o.length-1]){const t=re(o,5,-1),i=qt(t,"{");if(-1!==i&&(!Yt(re(t,0,i),"(")||null!==It(jn,jt(Bn,t))))return function(t,e,n){let r=`class ${$t(t,"name")&&t.name||"(anonymous)"}`;if("Function"!==e&&null!==e&&(r+=` [${e}]`),""!==n&&e!==n&&(r+=` [${n}]`),null!==e){const e=ht(t).name;e&&(r+=` extends ${e}`)}else r+=" extends [null prototype]";return`[${r}]`}(e,n,r)}let i="Function";Ue(e)&&(i=`Generator${i}`),He(e)&&(i=`Async${i}`);let s=`[${i}`;return null===n&&(s+=" (null prototype)"),""===e.name?s+=" (anonymous)":s+=`: ${"string"==typeof e.name?e.name:nr(t,e.name)}`,s+="]",n!==i&&null!==n&&(s+=` ${n}`),""!==r&&n!==r&&(s+=` [${r}]`),s}(t,e,c,u),0===s.length&&void 0===l)return t.stylize(d,"special")}else if("Object"===c){if(Ze(e)?f[0]="[Arguments] {":""!==u&&(f[0]=`${Xn(c,u,"Object")}{`),0===s.length&&void 0===l)return`${f[0]}}`}else if(ln(e)){d=Tt(null!==c?e:new Rt(e));const n=Xn(c,u,"RegExp");if("RegExp "!==n&&(d=`${n}${d}`),d=t.stylize(d,"regexp"),0===s.length&&void 0===l||o>t.depth&&null!==t.depth)return d}else if(cn(e)){d=rt(I(e))?B(e):j(e);const n=Xn(c,u,"Date");if("Date "!==n&&(d=`${n}${d}`),0===s.length&&void 0===l)return t.stylize(d,"date")}else if(Ce(e)){if(d=function(t,e,n,r,o){let i,s,l;try{l=ir(r,t)}catch{return xt(t)}let c=!1;try{i=t.message}catch{c=!0}let u=!1;try{s=t.name}catch{u=!0}if(!r.showHidden&&0!==o.length){const t=g(o,"stack");if(-1!==t&&P(o,t,1),!c){const t=g(o,"message");-1===t||"string"==typeof i&&!Yt(l,i)||P(o,t,1)}if(!u){const t=g(o,"name");-1===t||"string"==typeof s&&!Yt(l,s)||P(o,t,1)}}s=null==s?"Error":s,!$t(t,"cause")||0!==o.length&&y(o,"cause")||b(o,"cause");try{const e=t.errors;!a(e)||!$t(t,"errors")||0!==o.length&&y(o,"errors")||b(o,"errors")}catch{}l=function(t,e,n,r){let o=n.length;if("string"!=typeof n&&(t=ee(t,`${n}`,`${n} [${re(Xn(e,r,"Error"),0,-1)}]`)),null===e||Zt(n,"Error")&&ie(t,n)&&(t.length===o||":"===t[o]||"\n"===t[o])){let i="Error";if(null===e){const e=It(/^([A-Z][a-z_ A-Z0-9[\]()-]+)(?::|\n {4}at)/,t)||It(/^([a-z_A-Z0-9-]*Error)$/,t);i=e?.[1]||"",o=i.length,i=i||"Error"}const s=re(Xn(e,r,i),0,-1);n!==s&&(t=Yt(s,n)?0===o?`${s}: ${t}`:`${s}${re(t,o)}`:`${s} [${n}]${re(t,o)}`)}return t}(l,e,s,n);let f=i&&qt(l,i)||-1;-1!==f&&(f+=i.length);const p=qt(l,"\n at",f);if(-1===p)l=`[${l}]`;else{let e=re(l,0,p);const n=function(t,e,n){const r=oe(n,"\n");let o;try{({cause:o}=e)}catch{}if(null!=o&&Ce(o)){const e=ir(t,o),n=qt(e,"\n at");if(-1!==n){const o=oe(re(e,n+1),"\n"),{0:i,1:s}=or(r,o);if(i>0){const e=i-2,n=` ... ${e} lines matching cause stack trace ...`;r.splice(s+1,e,t.stylize(n,"undefined"))}}}if(r.length>10){const e=function(t){const e=[],n=new zt;for(let e=0;e<t.length;e++){const r=n.get(t[e]);void 0===r?n.set(t[e],[e]):r[r.length]=e}if(t.length-n.size<=3)return e;for(let r=0;r<t.length-3;r++){const o=n.get(t[r]);if(1===o.length||o[o.length-1]===r)continue;const i=o.indexOf(r)+1;if(i===o.length)continue;let s,l=o[o.length-1]-r;if(l<3)continue;if(i+1<o.length){let t=0;for(let e=i;e<o.length;e++){let n=o[e]-r;for(;0!==n;){const e=t%n;0!==t&&(s=s||new Mt,s.add(t)),t=n,n=e}if(1===t)break}l=t,s&&(s.delete(l),s=[...s])}let c=l,a=0,u=0;for(let e=r+l;;e+=l){let n=0;for(let o=0;o<l&&t[r+o]===t[e+o];o++)n++;if(n===l)u++;else{if(!s?.length)break;0!==u&&c*a<l*u&&(c=l,a=u),l=s.pop(),e=r,u=0}}0!==a&&c*a>=l*u&&(l=c,u=a),u*l>=3&&(e.push(r+l,l,u),r+=l*(u+1)-1)}return e}(r);for(let n=e.length-3;n>=0;n-=3){const o=e[n],i=e[n+1],s=e[n+2],l=` ... collapsed ${i*s} duplicate lines matching above `+(s>1?`${i} lines ${s} times...`:"lines ...");r.splice(o,i*s,t.stylize(l,"undefined"))}}return r}(r,t,re(l,p+1));if(r.colors){const t=function(){let t;try{t=process.cwd()}catch{return}return t}();let o;for(let i of n){const n=It(In,i);if(null!==n&&hn.exists(n[1]))e+=`\n${r.stylize(i,"undefined")}`;else{if(e+="\n",i=sr(r,i),void 0!==t){let e=lr(r,i,t);e===i&&(o=o||Pn(t),e=lr(r,i,o)),i=e}e+=i}}}else e+=`\n${h(n,"\n")}`;l=e}if(0!==r.indentationLvl){const t=te(" ",r.indentationLvl);l=ne(l,"\n",`\n${t}`)}return l}(e,c,u,t,s),0===s.length&&void 0===l)return d}else if(Ge(e)){const n=Xn(c,u,Ve(e)?"ArrayBuffer":"SharedArrayBuffer");if(void 0===i)m=hr;else if(0===s.length&&void 0===l)return n+`{ [byteLength]: ${ur(t.stylize,e.byteLength,!1)} }`;f[0]=`${n}{`,O=["byteLength"]}else if(qe(e))f[0]=`${Xn(c,u,"DataView")}{`,O=["byteLength","byteOffset","buffer"];else if(en(e))f[0]=`${Xn(c,u,"Promise")}{`,m=wr;else if(sn(e))f[0]=`${Xn(c,u,"WeakSet")}{`,m=t.showHidden?Ar:Pr;else if(on(e))f[0]=`${Xn(c,u,"WeakMap")}{`,m=t.showHidden?vr:Pr;else if(Xe(e))f[0]=`${Xn(c,u,"Module")}{`,m=yr.bind(null,s);else if(Ye(e)){if(d=function(t,e,n,r,o){let i,s;fn(t)?(i=ct,s="Number"):un(t)?(i=le,s="String",n.splice(0,t.length)):pn(t)?(i=E,s="Boolean"):yn(t)?(i=v,s="BigInt"):(i=ue,s="Symbol");let l=`[${s}`;return s!==r&&(l+=null===r?" (null prototype)":` (${r})`),l+=`: ${pr(Zn,i(t),e)}]`,""!==o&&o!==r&&(l+=` [${o}]`),0!==n.length||e.stylize===Zn?l:e.stylize(l,se(s))}(e,t,s,c,u),0===s.length&&void 0===l)return d}else if(!function(t){return Sn=Sn||n(511),"string"==typeof t.href&&t instanceof Sn.URL}(e)||o>t.depth&&null!==t.depth){if(0===s.length&&void 0===l){if(Je(e)){const n=ze(e).toString(16);return t.stylize(`[External: ${n}]`,"special")}return`${er(e,c,u)}{}`}f[0]=`${er(e,c,u)}{`}else if(s=function(t){return xn=xn||gt(new Sn.URL("http://user:pass@localhost:8080/?foo=bar#baz")),t.filter(t=>-1===xn[t])}(s),d=e.href,0===s.length&&void 0===l)return d;if(o>t.depth&&null!==t.depth){let n=re(er(e,c,u),0,-1);return null!==c&&(n=`[${n}]`),t.stylize(n,"special")}o+=1,t.seen.push(e),t.currentDepth=o;const k=t.indentationLvl;try{if(L=m(t,e,o),void 0!==O)for(p=0;p<O.length;p++){let n;try{n=Er(t,e,o,O[p],i)}catch{n=Er(t,{[O[p]]:e.buffer[O[p]]},o,O[p],i)}b(L,n)}for(p=0;p<s.length;p++)b(L,Or(t,e,o,s[p],R));void 0!==l&&$(L,l)}catch(n){if(!We(n))throw n;return function(t,e,n,r){return t.seen.pop(),t.indentationLvl=r,t.stylize(`[${n}: Inspection interrupted prematurely. Maximum call stack size exceeded.]`,"special")}(t,0,re(er(e,c,u),0,-1),k)}if(void 0!==t.circular){const n=t.circular.get(e);if(void 0!==n){const e=t.stylize(`<ref *${n}>`,"special");!0!==t.compact?d=""===d?e:`${e} ${d}`:f[0]=`${e} ${f[0]}`}}if(t.seen.pop(),t.sorted){const e=!0===t.sorted?void 0:t.sorted;if(0===R)x(L,e);else if(s.length>1){const t=x(S(L,L.length-s.length),e);A(t,L,L.length-s.length,s.length),Ot(P,null,t)}}const T=Rr(t,L,d,f,R,o,e),z=(t.budget[t.indentationLvl]||0)+T.length;return t.budget[t.indentationLvl]=z,z>2**27&&(t.depth=-1),T}(t,e,o,i)}function rr(t,e){return e!==`${t} Iterator`&&(""!==e&&(e+="] ["),e+=`${t} Iterator`),[`[${e}] {`,"}"]}function or(t,e){for(let n=0;n<t.length-3;n++){const r=g(e,t[n]);if(-1!==r){const o=e.length-r;if(o>3){let i=1;const s=K(t.length-n,o);for(;s>i&&t[n+i]===e[r+i];)i++;if(i>3)return[i,n]}}}return[0,0]}function ir(t,e){let n;try{n=e.stack}catch{}if(n){if("string"==typeof n)return n;t.seen.push(e),t.indentationLvl+=4;const r=nr(t,n);return t.indentationLvl-=4,t.seen.pop(),`${M(e)}\n ${r}`}return M(e)}function sr(t,e){let n="",r=0,o=0;for(;;){const i=qt(e,"node_modules",o);if(-1===i)break;const s=e[i-1],l=e[i+12];if("/"!==l&&"\\"!==l||"/"!==s&&"\\"!==s){o=i+1;continue}const c=i+13;n+=re(e,r,c);let a=qt(e,s,c);"@"===e[c]&&(a=qt(e,s,a+1));const u=re(e,c,a);n+=t.stylize(u,"module"),r=a,o=a}return 0!==r&&(e=n+re(e,r)),e}function lr(t,e,n){let r=qt(e,n),o="",i=n.length;if(-1!==r){"file://"===re(e,r-7,r)&&(i+=7,r-=7);const n="("===e[r-1]?r-1:r,s=n!==r&&Zt(e,")")?-1:e.length,l=r+i+1,c=re(e,n,l);o+=re(e,0,n),o+=t.stylize(c,"undefined"),o+=re(e,l,s),-1===s&&(o+=t.stylize(")","undefined"))}else o+=e;return o}function cr(t){let e="",n=t.length;gn(0!==n);const r="-"===t[0]?1:0;for(;n>=r+4;n-=3)e=`_${re(t,n-3,n)}${e}`;return n===t.length?t:`${re(t,0,n)}${e}`}const ar=t=>`... ${t} more item${t>1?"s":""}`;function ur(t,e,n){if(!n)return dt(e,-0)?t("-0","number"):t(`${e}`,"number");const r=Ht(e);if(tt(e)===e)return!nt(e)||Yt(r,"e")?t(r,"number"):t(cr(r),"number");if(rt(e))return t(r,"number");const o=qt(r,"."),i=re(r,0,o),s=re(r,o+1);return t(`${cr(i)}.${function(t){let e="",n=0;for(;n<t.length-3;n+=3)e+=`${re(t,n,n+3)}_`;return 0===n?t:`${e}${re(t,n)}`}(s)}`,"number")}function fr(t,e,n){const r=Ht(e);return t(n?`${cr(r)}n`:`${r}n`,"bigint")}function pr(t,e,n){if("string"==typeof e){let r="";if(e.length>n.maxStringLength){const t=e.length-n.maxStringLength;e=re(e,0,n.maxStringLength),r=`... ${t} more character${t>1?"s":""}`}return!0!==n.compact&&e.length>16&&e.length>n.breakLength-n.indentationLvl-4?h(d(Bt(/(?<=\n)/,e),e=>t(Gn(e),"string")),` +\n${te(" ",n.indentationLvl+2)}`)+r:t(Gn(e),"string")+r}return"number"==typeof e?ur(t,e,n.numericSeparator):"bigint"==typeof e?fr(t,e,n.numericSeparator):"boolean"==typeof e?t(`${e}`,"boolean"):void 0===e?t("undefined","undefined"):t(ae(e),"symbol")}function yr(t,e,n,r){const o=new s(t.length);for(let i=0;i<t.length;i++)try{o[i]=Or(e,n,r,t[i],0)}catch(n){gn(tn(n)&&"ReferenceError"===n.name);const s={[t[i]]:""};o[i]=Or(e,s,r,t[i],0);const l=Jt(o[i]," ");o[i]=re(o[i],0,l+1)+e.stylize("<uninitialized>","special")}return t.length=0,o}function gr(t,e,n,r,o,i){const s=mt(e);let l=i;for(;i<s.length&&o.length<r;i++){const c=s[i],a=+c;if(a>2**32-2)break;if(`${l}`!==c){if(null===It(kn,c))break;const e=a-l,n=`<${e} empty item${e>1?"s":""}>`;if(b(o,t.stylize(n,"undefined")),l=a,o.length===r)break}b(o,Or(t,e,n,c,1)),l++}const c=e.length-l;if(o.length!==r){if(c>0){const e=`<${c} empty item${c>1?"s":""}>`;b(o,t.stylize(e,"undefined"))}}else c>0&&b(o,ar(c));return o}function hr(t,e){let r;try{r=new $e(e)}catch{return[t.stylize("(detached)","special")]}void 0===$n&&($n=we(n(242).h.prototype.hexSlice));const o=$n(r,0,K(t.maxArrayLength,r.length));let i="",s=0;for(;s<o.length-2;s+=2)i+=`${o[s]}${o[s+1]} `;o.length>0&&(i+=`${o[s]}${o[s+1]}`);const l=r.length-t.maxArrayLength;return l>0&&(i+=` ... ${l} more byte${l>1?"s":""}`),[`${t.stylize("[Uint8Contents]","special")}: <${i}>`]}function dr(t,e,n){const r=e.length,o=K(J(0,t.maxArrayLength),r),i=r-o,s=[];for(let r=0;r<o;r++){const i=pt(e,r);if(void 0===i)return gr(t,e,n,o,s,r);b(s,Or(t,e,n,r,1,i))}return i>0&&b(s,ar(i)),s}function mr(t,e,n){const r=K(J(0,n.maxArrayLength),e),o=t.length-r,i=new s(r),l=t.length>0&&"number"==typeof t[0]?ur:fr;for(let e=0;e<r;++e)i[e]=l(n.stylize,t[e],n.numericSeparator);return o>0&&(i[r]=ar(o)),i}function br(t,e,n,r){const o=t.size,i=K(J(0,e.maxArrayLength),o),s=o-i,l=[];e.indentationLvl+=2;let c=0;for(const n of t){if(c>=i)break;b(l,nr(e,n,r)),c++}return s>0&&b(l,ar(s)),e.indentationLvl-=2,l}function $r(t,e,n,r){const o=t.size,i=K(J(0,e.maxArrayLength),o),s=o-i,l=[];e.indentationLvl+=2;let c=0;for(const{0:n,1:o}of t){if(c>=i)break;b(l,`${nr(e,n,r)} => ${nr(e,o,r)}`),c++}return s>0&&b(l,ar(s)),e.indentationLvl-=2,l}function Sr(t,e,n,r){const o=J(t.maxArrayLength,0),i=K(o,n.length),l=new s(i);t.indentationLvl+=2;for(let r=0;r<i;r++)l[r]=nr(t,n[r],e);t.indentationLvl-=2,0!==r||t.sorted||x(l);const c=n.length-i;return c>0&&b(l,ar(c)),l}function xr(t,e,n,r){const o=J(t.maxArrayLength,0),i=n.length/2,l=i-o,c=K(o,i),a=new s(c);let u=0;if(t.indentationLvl+=2,0===r){for(;u<c;u++){const r=2*u;a[u]=`${nr(t,n[r],e)} => ${nr(t,n[r+1],e)}`}t.sorted||x(a)}else for(;u<c;u++){const r=2*u,o=[nr(t,n[r],e),nr(t,n[r+1],e)];a[u]=Rr(t,o,"",["[","]"],2,e)}return t.indentationLvl-=2,l>0&&b(a,ar(l)),a}function Pr(t){return[t.stylize("<items unknown>","special")]}function Ar(t,e,n){return Sr(t,n,Be(e),0)}function vr(t,e,n){return xr(t,n,Be(e),0)}function _r(t,e,n,r){const{0:o,1:i}=Be(n,!0);return i?(t[0]=jt(/ Iterator] {$/,t[0]," Entries] {"),xr(e,r,o,2)):Sr(e,r,o,1)}function wr(t,e,n){let r;const{0:o,1:i}=Ie(e);if(o===Le)r=[t.stylize("<pending>","special")];else{t.indentationLvl+=2;const e=nr(t,i,n);t.indentationLvl-=2,r=[o===Re?`${t.stylize("<rejected>","special")} ${e}`:e]}return r}function Er(t,e,n,r,o){t.indentationLvl+=2;const i=nr(t,e[r],n,o);return t.indentationLvl-=2,`${t.stylize(`[${r}]`,"string")}: ${i}`}function Or(t,e,n,r,o,i,s=e){let l,c,a=" ";if(void 0!==(i=i||pt(e,r)).value){const e=!0!==t.compact||0!==o?2:3;t.indentationLvl+=e,c=nr(t,i.value,n),3===e&&t.breakLength<Mn(c,t.colors)&&(a=`\n${te(" ",t.indentationLvl)}`),t.indentationLvl-=e}else if(void 0!==i.get){const e=void 0!==i.set?"Getter/Setter":"Getter",r=t.stylize,o="special";if(t.getters&&(!0===t.getters||"get"===t.getters&&void 0===i.set||"set"===t.getters&&void 0!==i.set)){t.indentationLvl+=2;try{const l=D(i.get,s);if(null===l)c=`${r(`[${e}:`,o)} ${r("null","null")}${r("]",o)}`;else if("object"==typeof l)c=`${r(`[${e}]`,o)} ${nr(t,l,n)}`;else{const n=pr(r,l,t);c=`${r(`[${e}:`,o)} ${n}${r("]",o)}`}}catch(i){const s=`<Inspection threw (${nr(t,i,n)})>`;c=`${r(`[${e}:`,o)} ${s}${r("]",o)}`}t.indentationLvl-=2}else c=t.stylize(`[${e}]`,o)}else c=void 0!==i.set?t.stylize("[Setter]","special"):t.stylize("undefined","undefined");if(1===o)return c;if("symbol"==typeof r){const e=jt(En,ae(r),Un);l=t.stylize(e,"symbol")}else l=null!==It(Rn,r)?"__proto__"===r?"['__proto__']":t.stylize(r,"name"):t.stylize(Gn(r),"string");return!1===i.enumerable&&(l=`[${l}]`),`${l}:${a}${c}`}function Lr(t,e,n,r){let o=e.length+n;if(o+e.length>t.breakLength)return!1;for(let n=0;n<e.length;n++)if(t.colors?o+=De(e[n]).length:o+=e[n].length,o>t.breakLength)return!1;return""===r||!Yt(r,"\n")}function Rr(t,e,n,r,o,i,l){if(!0!==t.compact){if("number"==typeof t.compact&&t.compact>=1){const c=e.length;if(2===o&&c>6&&(e=function(t,e,n){let r=0,o=0,i=0,l=e.length;t.maxArrayLength<e.length&&l--;const c=new s(l);for(;i<l;i++){const n=Mn(e[i],t.colors);c[i]=n,r+=n+2,o<n&&(o=n)}const a=o+2;if(3*a+t.indentationLvl<t.breakLength&&(r/a>5||o<=6)){const o=2.5,i=X(a-r/e.length),s=J(a-3-i,1),u=K(Q(X(o*s*l)/s),q((t.breakLength-t.indentationLvl)/a),4*t.compact,15);if(u<=1)return e;const f=[],p=[];for(let t=0;t<u;t++){let n=0;for(let r=t;r<e.length;r+=u)c[r]>n&&(n=c[r]);n+=2,p[t]=n}let y=Xt;if(void 0!==n)for(let t=0;t<e.length;t++)if("number"!=typeof n[t]&&"bigint"!=typeof n[t]){y=Qt;break}for(let t=0;t<l;t+=u){const n=K(t+u,l);let r="",o=t;for(;o<n-1;o++){const n=p[o-t]+e[o].length-c[o];r+=y(`${e[o]}, `,n," ")}if(y===Xt){const n=p[o-t]+e[o].length-c[o]-2;r+=Xt(e[o],n," ")}else r+=e[o];b(f,r)}t.maxArrayLength<e.length&&b(f,e[l]),e=f}return e}(t,e,l)),t.currentDepth-i<t.compact&&c===e.length&&Lr(t,e,e.length+t.indentationLvl+r[0].length+n.length+10,n)){const t=Fe(e,", ");if(!Yt(t,"\n"))return`${n?`${n} `:""}${r[0]} ${t} ${r[1]}`}}const c=`\n${te(" ",t.indentationLvl)}`;return`${n?`${n} `:""}${r[0]}${c} ${Fe(e,`,${c} `)}${c}${r[1]}`}if(Lr(t,e,0,n))return`${r[0]}${n?` ${n}`:""} ${Fe(e,", ")} `+r[1];const c=te(" ",t.indentationLvl),a=""===n&&1===r[0].length?" ":`${n?` ${n}`:""}\n${c} `;return`${r[0]}${a}${Fe(e,`,\n${c} `)} ${r[1]}`}function kr(t){const e=je(t,!1);if(void 0!==e){if(null===e)return!0;t=e}let n=$t,r=$t;if("function"!=typeof t.toString){if("function"!=typeof t[fe])return!0;if($t(t,fe))return!1;n=Ir}else{if($t(t,"toString"))return!1;if("function"!=typeof t[fe])r=Ir;else if($t(t,fe))return!1}let o=t;do{o=ht(o)}while(!n(o,"toString")&&!r(o,fe));const i=pt(o,"constructor");return void 0!==i&&"function"==typeof i.value&&An.has(i.value.name)}function Ir(){return!1}const jr=t=>oe(t.message,"\n",1)[0];let Br;function Tr(t){try{return U(t)}catch(t){if(!Br)try{const t={};t.a=t,U(t)}catch(t){Br=jr(t)}if("TypeError"===t.name&&jr(t)===Br)return"[Circular]";throw t}}function zr(t,e){return ur(Zn,t,e?.numericSeparator??_n.numericSeparator)}function Mr(t,e){return fr(Zn,t,e?.numericSeparator??_n.numericSeparator)}function Nr(t,e){const n=e[0];let r=0,o="",i="";if("string"==typeof n){if(1===e.length)return n;let s,l=0;for(let i=0;i<n.length-1;i++)if(37===Gt(n,i)){const c=Gt(n,++i);if(r+1!==e.length){switch(c){case 115:{const n=e[++r];s="number"==typeof n?zr(n,t):"bigint"==typeof n?Mr(n,t):"object"==typeof n&&null!==n&&kr(n)?Nn(n,{...t,compact:3,colors:!1,depth:0}):Ht(n);break}case 106:s=Tr(e[++r]);break;case 100:{const n=e[++r];s="bigint"==typeof n?Mr(n,t):"symbol"==typeof n?"NaN":zr(et(n),t);break}case 79:s=Nn(e[++r],t);break;case 111:s=Nn(e[++r],{...t,showHidden:!0,showProxy:!0,depth:4});break;case 105:{const n=e[++r];s="bigint"==typeof n?Mr(n,t):"symbol"==typeof n?"NaN":zr(it(n),t);break}case 102:{const n=e[++r];s="symbol"==typeof n?"NaN":zr(ot(n),t);break}case 99:r+=1,s="";break;case 37:o+=re(n,l,i),l=i+1;continue;default:continue}l!==i-1&&(o+=re(n,l,i-1)),o+=s,l=i+1}else 37===c&&(o+=re(n,l,i),l=i+1)}0!==l&&(r++,i=" ",l<n.length&&(o+=re(n,l)))}for(;r<e.length;){const n=e[r];o+=i,o+="string"!=typeof n?Nn(n,t):n,i=" ",r++}return o}function Cr(t){return t<=31||t>=127&&t<=159||t>=768&&t<=879||t>=8203&&t<=8207||t>=8400&&t<=8447||t>=65024&&t<=65039||t>=65056&&t<=65071||t>=917760&&t<=917999}if(_e("config").hasIntl)gn(!1);else{Mn=function(e,n=!0){let r=0;n&&(e=Fr(e)),e=Kt(e,"NFC");for(const n of new Nt(e)){const e=Vt(n,0);t(e)?r+=2:Cr(e)||r++}return r};const t=t=>t>=4352&&(t<=4447||9001===t||9002===t||t>=11904&&t<=12871&&12351!==t||t>=12880&&t<=19903||t>=19968&&t<=42182||t>=43360&&t<=43388||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65131||t>=65281&&t<=65376||t>=65504&&t<=65510||t>=110592&&t<=110593||t>=127488&&t<=127569||t>=127744&&t<=128591||t>=131072&&t<=262141)}function Fr(t){return mn(t,"str"),-1===qt(t,"")&&-1===qt(t,"")?t:jt(zn,t,"")}const Dr={34:""",38:"&",39:"'",60:"<",62:">",160:" "};function Wr(t){return t.replace(/[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u00FF]/g,t=>{const e=Ht(t.charCodeAt(0));return Dr[e]||"&#"+e+";"})}t.exports={identicalSequenceRange:or,inspect:Nn,inspectDefaultOptions:_n,format:function(...t){return Nr(void 0,t)},formatWithOptions:function(t,...e){return dn(t,"inspectOptions",bn),Nr(t,e)},getStringWidth:Mn,stripVTControlCharacters:Fr,isZeroWidthCodePoint:Cr,stylizeWithColor:Vn,stylizeWithHTML(t,e){const n=Nn.styles[e];return void 0!==n?`<span style="color:${n};">${Wr(t)}</span>`:Wr(t)},Proxy:Me}},146(t,e,n){let r;function o(){return r=null!=r?r:n(923).codes.ERR_INTERNAL_ASSERTION}function i(t,e){if(!t)throw new(o())(e)}i.fail=function(t){throw new(o())(t)},t.exports=i},996(t){const e=["_http_agent","_http_client","_http_common","_http_incoming","_http_outgoing","_http_server","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_wrap","_stream_writable","_tls_common","_tls_wrap","assert","assert/strict","async_hooks","buffer","child_process","cluster","console","constants","crypto","dgram","diagnostics_channel","dns","dns/promises","domain","events","fs","fs/promises","http","http2","https","inspector","module","Module","net","os","path","path/posix","path/win32","perf_hooks","process","punycode","querystring","readline","readline/promises","repl","stream","stream/consumers","stream/promises","stream/web","string_decoder","sys","timers","timers/promises","tls","trace_events","tty","url","util","util/types","v8","vm","wasi","worker_threads","zlib"];t.exports.BuiltinModule={exists:t=>"internal/modules/cjs/foo"!==t&&(t.startsWith("internal/")||-1!==e.indexOf(t))}},575(t){t.exports={CHAR_DOT:46,CHAR_FORWARD_SLASH:47,CHAR_BACKWARD_SLASH:92}},923(t,e,n){const r=n(714),{ArrayIsArray:o,ArrayPrototypeIncludes:i,ArrayPrototypeIndexOf:s,ArrayPrototypeJoin:l,ArrayPrototypePush:c,ArrayPrototypeSlice:a,ArrayPrototypeSplice:u,Error:f,ErrorCaptureStackTrace:p,JSONStringify:y,ObjectDefineProperty:g,ReflectApply:h,RegExpPrototypeExec:d,SafeMap:m,SafeWeakMap:b,String:$,StringPrototypeEndsWith:S,StringPrototypeIncludes:x,StringPrototypeIndexOf:P,StringPrototypeSlice:A,StringPrototypeToLowerCase:v,Symbol:_,TypeError:w}=r,E=_("kIsNodeError"),O=new m,L={},R=/^[A-Z][a-zA-Z0-9]*$/,k=["string","function","number","object","Function","Object","boolean","bigint","symbol"],I=new b,j=n(146);let B,T,z=null;function M(t,e,n){O.set(t,e);const r=(o=n,i=t,class extends o{code=i;constructor(...t){super(),g(this,"message",{__proto__:null,value:N(i,t,this),enumerable:!1,writable:!0,configurable:!0})}toString(){return`${this.name} [${i}]: ${this.message}`}});var o,i;L[t]=r}function N(t,e,n){const r=O.get(t);if("function"==typeof r)return j(r.length<=e.length,`Code: ${t}; The provided arguments length (${e.length}) does not match the required ones (${r.length}).`),h(r,n,e)}const C=_("kEnhanceStackBeforeInspector");function F(t){if(null===t)return"null";if(void 0===t)return"undefined";switch(typeof t){case"bigint":return`type bigint (${t}n)`;case"number":return 0===t?1/t==-1/0?"type number (-0)":"type number (0)":t!=t?"type number (NaN)":t===1/0?"type number (Infinity)":t===-1/0?"type number (-Infinity)":`type number (${t})`;case"boolean":return t?"type boolean (true)":"type boolean (false)";case"symbol":return`type symbol (${$(t)})`;case"function":return`function ${t.name}`;case"object":return t.constructor&&"name"in t.constructor?`an instance of ${t.constructor.name}`:`${(z=z||n(702),z).inspect(t,{depth:-1})}`;case"string":return t.length>28&&(t=`${A(t,0,25)}...`),-1===P(t,"'")?`type string ('${t}')`:`type string (${y(t)})`}}function D(t,e="and"){switch(t.length){case 0:return"";case 1:return`${t[0]}`;case 2:return`${t[0]} ${e} ${t[1]}`;case 3:return`${t[0]}, ${t[1]}, ${e} ${t[2]}`;default:return`${l(a(t,0,-1),", ")}, ${e} ${t[t.length-1]}`}}t.exports={codes:L,determineSpecificType:F,E:M,formatList:D,getMessage:N,hideStackFrames:function(t){function e(...n){try{return h(t,this,n)}catch(t){throw f.stackTraceLimit&&p(t,e),t}}return e.withoutStackTrace=t,e},isStackOverflowError:function(t){if(void 0===T)try{function e(){e()}e()}catch(t){T=t.message,B=t.name}return t&&t.name===B&&t.message===T},kEnhanceStackBeforeInspector:C,kIsNodeError:E,overrideStackTrace:I},M("ERR_INTERNAL_ASSERTION",t=>{const e="This is caused by either a bug in Node.js or incorrect usage of Node.js internals.\nPlease open an issue with this stack trace at https://github.com/nodejs/node/issues\n";return void 0===t?e:`${t}\n${e}`},f),M("ERR_INVALID_ARG_TYPE",(t,e,n)=>{j("string"==typeof t,"'name' must be a string"),o(e)||(e=[e]);let r="The ";S(t," argument")?r+=`${t} `:r+=`"${t}" ${x(t,".")?"property":"argument"} `,r+="must be ";const l=[],a=[],f=[];for(const t of e)j("string"==typeof t,"All expected entries have to be of type string"),i(k,t)?c(l,v(t)):null!==d(R,t)?c(a,t):(j("object"!==t,'The value "object" should be written as "Object"'),c(f,t));if(a.length>0){const t=s(l,"object");-1!==t&&(u(l,t,1),c(a,"Object"))}return l.length>0&&(r+=`${l.length>1?"one of type":"of type"} ${D(l,"or")}`,(a.length>0||f.length>0)&&(r+=" or ")),a.length>0&&(r+=`an instance of ${D(a,"or")}`,f.length>0&&(r+=" or ")),f.length>0&&(f.length>1?r+=`one of ${D(f,"or")}`:(v(f[0])!==f[0]&&(r+="an "),r+=`${f[0]}`)),r+=`. Received ${F(n)}`,r},w)},511(t,e,n){const{StringPrototypeCharCodeAt:r,StringPrototypeIncludes:o,StringPrototypeReplace:i}=n(714),s=n(851),{CHAR_FORWARD_SLASH:l}=n(575),c=n(811),a=/%/g,u=/\\/g,f=/\n/g,p=/\r/g,y=/\t/g;t.exports={pathToFileURL:function(t){const e=new s("file://");let n=c.resolve(t);return r(t,t.length-1)===l&&n[n.length-1]!==c.sep&&(n+="/"),e.pathname=function(t){return o(t,"%")&&(t=i(t,a,"%25")),o(t,"\\")&&(t=i(t,u,"%5C")),o(t,"\n")&&(t=i(t,f,"%0A")),o(t,"\r")&&(t=i(t,p,"%0D")),o(t,"\t")&&(t=i(t,y,"%09")),t}(n),e},URL:s}},992(t,e,n){const r=n(714),{ArrayPrototypeJoin:o,Error:i,ErrorIsError:s,FunctionPrototypeSymbolHasInstance:l,StringPrototypeReplace:c,SymbolFor:a}=r,u=/\u001b\[\d\d?m/g;t.exports={customInspectSymbol:a("nodejs.util.inspect.custom"),isError:t=>s?.(t)||l(i,t),join:o,removeColors:t=>c(t,u,"")}},134(t,e,n){const r=n(714),{ArrayIsArray:o,BigInt:i,Boolean:s,DatePrototype:l,Error:c,FunctionPrototype:a,MapPrototypeHas:u,Number:f,ObjectDefineProperty:p,ObjectGetOwnPropertyDescriptor:y,ObjectGetPrototypeOf:g,ObjectIsFrozen:h,ObjectPrototype:d,SetPrototypeHas:m,String:b,Symbol:$,SymbolToStringTag:S,globalThis:x}=r,{getConstructorName:P}=n(596);function A(t,...e){for(const n of e){const e=x[n];if(e&&t instanceof e)return!0}for(;t;){if("object"!=typeof t)return!1;if(e.indexOf(P(t))>=0)return!0;t=g(t)}return!1}function v(t){return e=>{if(!A(e,t.name))return!1;try{t.prototype.valueOf.call(e)}catch{return!1}return!0}}"object"!=typeof x&&(p(d,"__magic__",{get:function(){return this},configurable:!0}),__magic__.globalThis=__magic__,delete d.__magic__);const _=v(b),w=v(f),E=v(s),O=v(i),L=v($);t.exports={isAsyncFunction:t=>"function"==typeof t&&a.toString.call(t).startsWith("async"),isGeneratorFunction:t=>"function"==typeof t&&a.toString.call(t).match(/^(async\s+)?function *\*/),isAnyArrayBuffer:t=>A(t,"ArrayBuffer","SharedArrayBuffer"),isArrayBuffer:t=>A(t,"ArrayBuffer"),isArgumentsObject(t){if(null!==t&&"object"==typeof t&&!o(t)&&"number"==typeof t.length&&t.length===(0|t.length)&&t.length>=0){const e=y(t,"callee");return e&&!e.enumerable}return!1},isBoxedPrimitive:t=>w(t)||_(t)||E(t)||O(t)||L(t),isDataView:t=>A(t,"DataView"),isExternal:t=>"object"==typeof t&&h(t)&&null==g(t),isMap(t){if(!A(t,"Map"))return!1;try{u(t)}catch{return!1}return!0},isMapIterator:t=>"[object Map Iterator]"===d.toString.call(g(t)),isModuleNamespaceObject(t){try{return t&&"object"==typeof t&&"Module"===t[S]}catch{return!1}},isNativeError:t=>t instanceof c&&A(t,"Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError","AggregateError"),isPromise:t=>A(t,"Promise"),isSet(t){if(!A(t,"Set"))return!1;try{m(t)}catch{return!1}return!0},isSetIterator:t=>"[object Set Iterator]"===d.toString.call(g(t)),isWeakMap:t=>A(t,"WeakMap"),isWeakSet:t=>A(t,"WeakSet"),isRegExp:t=>A(t,"RegExp"),isDate(t){if(A(t,"Date"))try{return l.getTime.call(t),!0}catch{}return!1},isTypedArray:t=>A(t,"Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"),isStringObject:_,isNumberObject:w,isBooleanObject:E,isBigIntObject:O,isSymbolObject:L}},63(t,e,n){const{ArrayIsArray:r}=n(714),{hideStackFrames:o,codes:{ERR_INVALID_ARG_TYPE:i}}=n(923),s=o((t,e,n=0)=>{if(0===n){if(null===t||r(t))throw new i(e,"Object",t);if("object"!=typeof t)throw new i(e,"Object",t)}else{if(!(1&n)&&null===t)throw new i(e,"Object",t);if(!(2&n)&&r(t))throw new i(e,"Object",t);const o=typeof t;if(!("object"===o||4&n&&"function"===o))throw new i(e,"Object",t)}});t.exports={kValidateObjectNone:0,kValidateObjectAllowNullable:1,kValidateObjectAllowArray:2,kValidateObjectAllowFunction:4,validateObject:s,validateString:function(t,e){if("string"!=typeof t)throw new i(e,"string",t)}}},811(t,e,n){const{StringPrototypeCharCodeAt:r,StringPrototypeLastIndexOf:o,StringPrototypeSlice:i}=n(714),{CHAR_DOT:s,CHAR_FORWARD_SLASH:l}=n(575),{validateString:c}=n(63);function a(t){return t===l}function u(t,e,n,c){let a="",u=0,f=-1,p=0,y=0;for(let g=0;g<=t.length;++g){if(g<t.length)y=r(t,g);else{if(c(y))break;y=l}if(c(y)){if(f===g-1||1===p);else if(2===p){if(a.length<2||2!==u||r(a,a.length-1)!==s||r(a,a.length-2)!==s){if(a.length>2){const t=o(a,n);-1===t?(a="",u=0):(a=i(a,0,t),u=a.length-1-o(a,n)),f=g,p=0;continue}if(0!==a.length){a="",u=0,f=g,p=0;continue}}e&&(a+=a.length>0?`${n}..`:"..",u=2)}else a.length>0?a+=`${n}${i(t,f+1,g)}`:a=i(t,f+1,g),u=g-f-1;f=g,p=0}else y===s&&-1!==p?++p:p=-1}return a}t.exports={isPosixPathSeparator:a,normalizeString:u,resolve:function(...t){if(0===t.length||1===t.length&&(""===t[0]||"."===t[0])){const t="/";if(r(t,0)===l)return t}let e="",n=!1;for(let o=t.length-1;o>=0&&!n;o--){const i=t[o];c(i,`paths[${o}]`),0!==i.length&&(e=`${i}/${e}`,n=r(i,0)===l)}if(!n){const t="/";e=`${t}/${e}`,n=r(t,0)===l}return e=u(e,!n,"/",a),n?`/${e}`:e.length>0?e:"."}}},714(t){const e={__proto__:null},{defineProperty:n,getOwnPropertyDescriptor:r,ownKeys:o}=Reflect,{apply:i,bind:s,call:l}=Function.prototype,c=s.bind(l);e.uncurryThis=c;const a=s.bind(i);e.applyBind=a;const u=["ArrayOf","ArrayPrototypePush","ArrayPrototypeUnshift","MathHypot","MathMax","MathMin","StringFromCharCode","StringFromCodePoint","StringPrototypeConcat","TypedArrayOf"];function f(t){return"symbol"==typeof t?`Symbol${t.description[7].toUpperCase()}${t.description.slice(8)}`:`${t[0].toUpperCase()}${t.slice(1)}`}function p(t,e,r,{enumerable:o,get:i,set:s}){n(t,`${e}Get${r}`,{__proto__:null,value:c(i),enumerable:o}),void 0!==s&&n(t,`${e}Set${r}`,{__proto__:null,value:c(s),enumerable:o})}function y(t,e,i){for(const s of o(t)){const o=f(s),l=r(t,s);if("get"in l)p(e,i,o,l);else{const r=`${i}${o}`;n(e,r,{__proto__:null,...l}),u.includes(r)&&n(e,`${r}Apply`,{__proto__:null,value:a(l.value,t)})}}}function g(t,e,i){for(const s of o(t)){const o=f(s),l=r(t,s);if("get"in l)p(e,i,o,l);else{const{value:t}=l;"function"==typeof t&&(l.value=c(t));const r=`${i}${o}`;n(e,r,{__proto__:null,...l}),u.includes(r)&&n(e,`${r}Apply`,{__proto__:null,value:a(t)})}}}["Proxy","globalThis"].forEach(t=>{e[t]=globalThis[t]}),[decodeURI,decodeURIComponent,encodeURI,encodeURIComponent].forEach(t=>{e[t.name]=t}),[escape,eval,unescape].forEach(t=>{e[t.name]=t}),["Atomics","JSON","Math","Proxy","Reflect"].forEach(t=>{y(globalThis[t],e,t)}),["AggregateError","Array","ArrayBuffer","BigInt","BigInt64Array","BigUint64Array","Boolean","DataView","Date","Error","EvalError","FinalizationRegistry","Float32Array","Float64Array","Function","Int16Array","Int32Array","Int8Array","Map","Number","Object","RangeError","ReferenceError","RegExp","Set","String","Symbol","SyntaxError","TypeError","URIError","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","WeakMap","WeakRef","WeakSet"].forEach(t=>{const n=globalThis[t];n&&(e[t]=n,y(n,e,t),g(n.prototype,e,`${t}Prototype`))}),["Promise"].forEach(t=>{const i=globalThis[t];e[t]=i,function(t,e,i){for(const s of o(t)){const o=f(s),l=r(t,s);if("get"in l)p(e,i,o,l);else{const{value:r}=l;"function"==typeof r&&(l.value=r.bind(t)),n(e,`${i}${o}`,{__proto__:null,...l})}}}(i,e,t),g(i.prototype,e,`${t}Prototype`)}),[{name:"TypedArray",original:Reflect.getPrototypeOf(Uint8Array)},{name:"ArrayIterator",original:{prototype:Reflect.getPrototypeOf(Array.prototype[Symbol.iterator]())}},{name:"StringIterator",original:{prototype:Reflect.getPrototypeOf(String.prototype[Symbol.iterator]())}}].forEach(({name:t,original:n})=>{e[t]=n,g(n,e,t),g(n.prototype,e,`${t}Prototype`)}),e.IteratorPrototype=Reflect.getPrototypeOf(e.ArrayIteratorPrototype);const{ArrayPrototypeForEach:h,ArrayPrototypePushApply:d,ArrayPrototypeSlice:m,FinalizationRegistry:b,FunctionPrototypeCall:$,Map:S,ObjectFreeze:x,ObjectSetPrototypeOf:P,RegExp:A,Set:v,SymbolIterator:_,WeakMap:w,WeakRef:E,WeakSet:O}=e,L=(t,e)=>{class n{constructor(e){this._iterator=t(e)}next(){return e(this._iterator)}[_](){return this}}return P(n.prototype,null),x(n.prototype),x(n),n};e.SafeArrayIterator=L(e.ArrayPrototypeSymbolIterator,e.ArrayIteratorPrototypeNext),e.SafeStringIterator=L(e.StringPrototypeSymbolIterator,e.StringIteratorPrototypeNext);const R=(t,e)=>{h(o(t),o=>{r(e,o)||n(e,o,{__proto__:null,...r(t,o)})})},k=(t,e)=>{if(_ in t.prototype){const i=new t;let s;h(o(t.prototype),o=>{if(!r(e.prototype,o)){const l=r(t.prototype,o);if("function"==typeof l.value&&0===l.value.length&&_ in($(l.value,i)??{})){const t=c(l.value);s=s||c(t(i).next);const e=L(t,s);l.value=function(){return new e(this)}}n(e.prototype,o,{__proto__:null,...l})}})}else R(t.prototype,e.prototype);return R(t,e),P(e.prototype,null),x(e.prototype),x(e),e};e.makeSafe=k,e.SafeMap=k(S,class extends S{}),e.SafeWeakMap=k(w,class extends w{}),e.SafeSet=k(v,class extends v{}),e.SafeWeakSet=k(O,class extends O{}),e.SafeFinalizationRegistry=k(b,class extends b{}),e.SafeWeakRef=k(E,class extends E{}),e.AsyncIteratorPrototype=e.ReflectGetPrototypeOf(async function*(){}).prototype,e.internalBinding=t=>{if("config"===t)return{hasIntl:!1};throw new Error(`unknown module: "${t}"`)},e._stringPrototypeReplaceAll=(t,e,n)=>"[object regexp]"===Object.prototype.toString.call(e).toLowerCase()?t.replace(e,n):t.replace(new A(e,"g"),n),e.SafeArrayPrototypePushApply=(t,e)=>{let n=65536;if(n<e.length){let r=0;do{d(t,m(e,r,r=n)),n+=65536}while(n<e.length);e=m(e,r)}return d(t,e)},e.StringPrototypeReplaceAll=e.StringPrototypeReplaceAll||e._stringPrototypeReplaceAll,P(e,null),x(e),t.exports=e},326(t,e,n){const r=n(714),{Proxy:o,ProxyRevocable:i,SafeWeakMap:s}=r,l=new s;class c{constructor(t,e){const n=new o(t,e);return l.set(n,[t,e]),n}static getProxyDetails(t,e=!0){const n=l.get(t);if(n)return e?n:n[0]}static revocable(t,e){const n=i(t,e);l.set(n.proxy,[t,e]);const r=n.revoke;return n.revoke=()=>{l.set(n.proxy,[null,null]),r()},n}}t.exports={getProxyDetails:c.getProxyDetails.bind(c),Proxy:c}},851(t){t.exports=URL},596(t,e,n){const r=n(714),{BigInt:o,Error:i,NumberParseInt:s,ObjectEntries:l,ObjectGetOwnPropertyDescriptor:c,ObjectGetOwnPropertyDescriptors:a,ObjectGetOwnPropertySymbols:u,ObjectPrototypeToString:f,Symbol:p}=r,y=n(326),g=p("kPending"),h=p("kRejected");t.exports={constants:{kPending:g,kRejected:h,ALL_PROPERTIES:0,ONLY_ENUMERABLE:2},getOwnNonIndexProperties:function(t,e=2){const n=a(t),r=[];for(const[t,o]of l(n))if(!/^(0|[1-9][0-9]*)$/.test(t)||s(t,10)>=2**32-1){if(2===e&&!o.enumerable)continue;r.push(t)}for(const n of u(t)){const o=c(t,n);(2!==e||o.enumerable)&&r.push(n)}return r},getPromiseDetails:()=>[g,void 0],getProxyDetails:y.getProxyDetails,Proxy:y.Proxy,previewEntries:t=>[[],!1],getConstructorName(t){if(!t||"object"!=typeof t)throw new i("Invalid object");if(t.constructor?.name)return t.constructor.name;const e=f(t).match(/^\[object ([^\]]+)\]/);return e?e[1]:"Object"},getExternalValue:()=>o(0)}}},e={};return function n(r){var o=e[r];if(void 0!==o)return o.exports;var i=e[r]={exports:{}};return t[r](i,i.exports,n),i.exports}(702)})());
|
|
48769
49290
|
|
|
49291
|
+
/***/ },
|
|
49292
|
+
|
|
49293
|
+
/***/ "./node_modules/time-commando/index.js"
|
|
49294
|
+
/*!*********************************************!*\
|
|
49295
|
+
!*** ./node_modules/time-commando/index.js ***!
|
|
49296
|
+
\*********************************************/
|
|
49297
|
+
(__unused_webpack_module, exports) {
|
|
49298
|
+
|
|
49299
|
+
"use strict";
|
|
49300
|
+
|
|
49301
|
+
|
|
49302
|
+
/**
|
|
49303
|
+
* Creates a new Date object from the given value.
|
|
49304
|
+
*
|
|
49305
|
+
* @param {any} val - The value to create the Date object from.
|
|
49306
|
+
* @returns {Date} A new Date object.
|
|
49307
|
+
*/
|
|
49308
|
+
|
|
49309
|
+
exports.D = function(val) {
|
|
49310
|
+
return new Date(val);
|
|
49311
|
+
};
|
|
49312
|
+
|
|
49313
|
+
/**
|
|
49314
|
+
* Creates a new Date object representing the current date and time.
|
|
49315
|
+
*
|
|
49316
|
+
* @returns {Date} A new Date object representing the current date and time.
|
|
49317
|
+
*/
|
|
49318
|
+
|
|
49319
|
+
exports.now = function now() {
|
|
49320
|
+
return new Date();
|
|
49321
|
+
};
|
|
49322
|
+
|
|
49323
|
+
/**
|
|
49324
|
+
* Creates a new Date object representing the next midnight from the given date.
|
|
49325
|
+
* If no date is provided, it defaults to the current date and time.
|
|
49326
|
+
*
|
|
49327
|
+
* @param {Date} [date] - The date from which to calculate the next midnight.
|
|
49328
|
+
* @returns {Date} A new Date object representing the next midnight.
|
|
49329
|
+
*/
|
|
49330
|
+
|
|
49331
|
+
exports.nextMidnight = function nextMidnight(date) {
|
|
49332
|
+
date = date ?? exports.now();
|
|
49333
|
+
date.setDate(date.getDate() + 1);
|
|
49334
|
+
date.setHours(0, 0, 0, 0);
|
|
49335
|
+
return date;
|
|
49336
|
+
};
|
|
49337
|
+
|
|
49338
|
+
/**
|
|
49339
|
+
* Converts a Date object to a string in the format 'YYYYMMDD' or 'YYYY-MM-DD'
|
|
49340
|
+
*
|
|
49341
|
+
* @param {Date} d - The Date object to be converted
|
|
49342
|
+
* @param {Boolean} dashes - Set to true to return 'YYYY-MM-DD'
|
|
49343
|
+
* @returns {string} A string representing the desired format
|
|
49344
|
+
*/
|
|
49345
|
+
|
|
49346
|
+
exports.toYYYYMMDD = function toYYYYMMDD(d, dashes) {
|
|
49347
|
+
if (dashes) {
|
|
49348
|
+
const year = d.getFullYear();
|
|
49349
|
+
const month = d.getMonth() + 1;
|
|
49350
|
+
const day = d.getDate();
|
|
49351
|
+
return year + '-' + ('' + month).padStart(2, '0') + '-' + ('' + day).padStart(2, '0'); // "2021-11-24"
|
|
49352
|
+
}
|
|
49353
|
+
const year = d.getFullYear() * 1e4;
|
|
49354
|
+
const month = (d.getMonth() + 1) * 100;
|
|
49355
|
+
const day = d.getDate();
|
|
49356
|
+
return year + month + day + ''; // `+ ''` to convert to string from number, 20211124 => "20211124"
|
|
49357
|
+
};
|
|
49358
|
+
|
|
49359
|
+
exports.oneSecondMS = 1000;
|
|
49360
|
+
exports.oneMinuteMS = exports.oneSecondMS * 60;
|
|
49361
|
+
exports.oneHourMS = exports.oneMinuteMS * 60;
|
|
49362
|
+
exports.oneDayMS = exports.oneHourMS * 24;
|
|
49363
|
+
exports.oneWeekMS = exports.oneDayMS * 7;
|
|
49364
|
+
|
|
49365
|
+
/**
|
|
49366
|
+
* Return the number of milliseconds in `num` seconds
|
|
49367
|
+
*
|
|
49368
|
+
* @param {number} num - The number of seconds to convert to milliseconds.
|
|
49369
|
+
* @returns {number} The equivalent number of milliseconds.
|
|
49370
|
+
*/
|
|
49371
|
+
|
|
49372
|
+
exports.seconds = function seconds(num) {
|
|
49373
|
+
if (typeof num !== 'number') {
|
|
49374
|
+
throw new TypeError('Parameter must be a number, got ' + typeof num);
|
|
49375
|
+
}
|
|
49376
|
+
return num * time.oneSecondMS;
|
|
49377
|
+
};
|
|
49378
|
+
|
|
49379
|
+
/**
|
|
49380
|
+
* Return the number of milliseconds in `num` minutes
|
|
49381
|
+
*
|
|
49382
|
+
* @param {number} num - The number of minutes to convert to milliseconds.
|
|
49383
|
+
* @returns {number} The equivalent number of milliseconds.
|
|
49384
|
+
*/
|
|
49385
|
+
|
|
49386
|
+
exports.minutes = function minutes(num) {
|
|
49387
|
+
if (typeof num !== 'number') {
|
|
49388
|
+
throw new TypeError('Parameter must be a number, got ' + typeof num);
|
|
49389
|
+
}
|
|
49390
|
+
return num * time.oneMinuteMS;
|
|
49391
|
+
};
|
|
49392
|
+
|
|
49393
|
+
/**
|
|
49394
|
+
* Return the number of milliseconds in `num` hours
|
|
49395
|
+
*
|
|
49396
|
+
* @param {number} num - The number of hours to convert to milliseconds.
|
|
49397
|
+
* @returns {number} The equivalent number of milliseconds.
|
|
49398
|
+
*/
|
|
49399
|
+
|
|
49400
|
+
exports.hours = function hours(num) {
|
|
49401
|
+
if (typeof num !== 'number') {
|
|
49402
|
+
throw new TypeError('Parameter must be a number, got ' + typeof num);
|
|
49403
|
+
}
|
|
49404
|
+
return num * time.oneHourMS;
|
|
49405
|
+
};
|
|
49406
|
+
|
|
49407
|
+
/**
|
|
49408
|
+
* Return the number of milliseconds in `num` days
|
|
49409
|
+
*
|
|
49410
|
+
* @param {number} num - The number of days to convert to milliseconds.
|
|
49411
|
+
* @returns {number} The equivalent number of milliseconds.
|
|
49412
|
+
*/
|
|
49413
|
+
|
|
49414
|
+
exports.days = function days(num) {
|
|
49415
|
+
if (typeof num !== 'number') {
|
|
49416
|
+
throw new TypeError('Parameter must be a number, got ' + typeof num);
|
|
49417
|
+
}
|
|
49418
|
+
return num * time.oneDayMS;
|
|
49419
|
+
};
|
|
49420
|
+
|
|
49421
|
+
/**
|
|
49422
|
+
* Return the number of milliseconds in `num` weeks
|
|
49423
|
+
*
|
|
49424
|
+
* @param {number} num - The number of weeks to convert to milliseconds.
|
|
49425
|
+
* @returns {number} The equivalent number of milliseconds.
|
|
49426
|
+
*/
|
|
49427
|
+
|
|
49428
|
+
exports.weeks = function weeks(num) {
|
|
49429
|
+
if (typeof num !== 'number') {
|
|
49430
|
+
throw new TypeError('Parameter must be a number, got ' + typeof num);
|
|
49431
|
+
}
|
|
49432
|
+
return num * time.oneWeekMS;
|
|
49433
|
+
};
|
|
49434
|
+
|
|
49435
|
+
|
|
48770
49436
|
/***/ },
|
|
48771
49437
|
|
|
48772
49438
|
/***/ "./node_modules/vue/dist/vue.runtime.esm-bundler.js"
|
|
@@ -48953,7 +49619,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
48953
49619
|
/* harmony import */ var _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @vue/runtime-dom */ "./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js");
|
|
48954
49620
|
/* harmony import */ var _vue_runtime_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @vue/runtime-dom */ "./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js");
|
|
48955
49621
|
/**
|
|
48956
|
-
* vue v3.5.
|
|
49622
|
+
* vue v3.5.32
|
|
48957
49623
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
48958
49624
|
* @license MIT
|
|
48959
49625
|
**/
|
|
@@ -50118,7 +50784,7 @@ module.exports = "<div class=\"relative flex items-start\" :class=\"{'justify-en
|
|
|
50118
50784
|
(module) {
|
|
50119
50785
|
|
|
50120
50786
|
"use strict";
|
|
50121
|
-
module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <button\n type=\"button\"\n class=\"fixed top-[65px] left-0 cursor-pointer bg-muted rounded-r-md p-1\"\n :class=\"hideSidebar === true ? 'z-[10001]' : hideSidebar === false ? 'z-10' : 'z-30 lg:hidden'\"\n @click=\"hideSidebar = hideSidebar === false ? true : false\"\n aria-label=\"Toggle chat history\"\n title=\"Toggle chat history\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5 text-content-tertiary\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n
|
|
50787
|
+
module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <button\n type=\"button\"\n class=\"fixed top-[65px] left-0 cursor-pointer bg-muted rounded-r-md p-1\"\n :class=\"hideSidebar === true ? 'z-[10001]' : hideSidebar === false ? 'z-10' : 'z-30 lg:hidden'\"\n @click=\"hideSidebar = hideSidebar === false ? true : false\"\n aria-label=\"Toggle chat history\"\n title=\"Toggle chat history\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5 text-content-tertiary\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n <!-- Sidebar: Chat Threads -->\n <aside\n class=\"bg-page border-r overflow-hidden h-full transition-all duration-300 ease-in-out z-20 w-64 fixed lg:relative shrink-0 flex flex-col\"\n :class=\"hideSidebar === false ? 'translate-x-0' : hideSidebar === true ? '-translate-x-full lg:translate-x-0 lg:!w-0 lg:!border-r-0' : '-translate-x-full lg:translate-x-0'\"\n style=\"z-index: 1000\">\n <!-- Search + New Thread -->\n <div class=\"p-3 shrink-0\">\n <div class=\"relative flex items-center gap-2\">\n <div class=\"relative flex-1\">\n <svg class=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n <input\n v-model=\"threadSearch\"\n type=\"text\"\n placeholder=\"Search threads...\"\n @keydown.esc=\"threadSearch = ''\"\n class=\"w-full rounded-md border border-edge bg-surface py-1.5 pl-8 pr-3 text-sm text-content placeholder:text-gray-400 focus:border-edge-strong focus:outline-none focus:ring-1 focus:ring-gray-300\"\n />\n </div>\n <async-button\n @click=\"createNewThread\"\n class=\"shrink-0 rounded-md border border-edge bg-surface p-1.5 text-content-tertiary hover:bg-muted hover:text-content-secondary\"\n title=\"New thread\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n </async-button>\n </div>\n </div>\n <!-- Thread list (scrollable) -->\n <nav class=\"flex-1 overflow-y-auto px-2 pb-2\">\n <div class=\"px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider\">Threads</div>\n <div v-if=\"status === 'loaded' && filteredThreads.length === 0\" class=\"px-2 py-2 text-sm text-content-tertiary\">\n <template v-if=\"threadSearch.trim()\">No threads match \"{{threadSearch}}\"</template>\n <template v-else>No threads yet</template>\n </div>\n <ul role=\"list\">\n <li\n v-for=\"thread in filteredThreads\"\n :key=\"thread._id\"\n @click=\"selectThread(thread._id)\"\n class=\"rounded-md py-2 px-2 cursor-pointer mb-0.5\"\n :class=\"thread._id === chatThreadId ? 'bg-gray-200 text-content' : 'hover:bg-muted text-content-secondary'\"\n >\n <div class=\"text-sm font-medium truncate\">{{ thread.title || 'Untitled Thread' }}</div>\n <div class=\"text-xs text-gray-400 mt-0.5\">{{ formatThreadDate(thread.updatedAt || thread.createdAt) }}</div>\n </li>\n </ul>\n </nav>\n <!-- Bottom toolbar -->\n <div class=\"shrink-0 border-t border-edge bg-page px-2 py-1.5 flex items-center gap-1\">\n <button\n type=\"button\"\n @click=\"hideSidebar = true\"\n class=\"rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n title=\"Hide sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5\" />\n </svg>\n </button>\n <button\n type=\"button\"\n @click=\"hasWorkspace ? toggleShareThread() : (showProUpgradeModal = true)\"\n class=\"rounded p-1.5\"\n :class=\"hasWorkspace && chatThreadId ? 'text-gray-400 hover:text-gray-600 hover:bg-muted' : !hasWorkspace ? 'text-gray-400 hover:text-gray-600 hover:bg-muted' : 'text-gray-300 cursor-not-allowed'\"\n :disabled=\"hasWorkspace && !chatThreadId\"\n aria-label=\"Share thread with workspace\"\n :title=\"'Share thread with workspace' + (!hasWorkspace ? ' (requires a pro workspace)' : !chatThreadId ? ': Open a thread first!' : '')\"\n >\n <svg v-if=\"hasWorkspace\" xmlns=\"http://www.w3.org/2000/svg\" class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7a2.48 2.48 0 0 0 0-1.39l7.02-4.11a2.5 2.5 0 1 0-.87-1.37L8.04 9.94a2.5 2.5 0 1 0 0 4.12l7.12 4.16a2.5 2.5 0 1 0 .84-1.34l-7.05-4.12c-.04-.02-.08-.05-.11-.07a2.48 2.48 0 0 0 0-1.39c.03-.02.07-.04.11-.07l7.11-4.16c.52.47 1.2.76 1.94.76a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0-1.94.94L7.97 8.43a2.5 2.5 0 1 0 0 7.14l9.09 5.3c.52-.47 1.2-.76 1.94-.76a2.5 2.5 0 1 0 0-5z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"w-4 h-4\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12 1a5 5 0 00-5 5v3H6a2 2 0 00-2 2v9a2 2 0 002 2h12a2 2 0 002-2v-9a2 2 0 00-2-2h-1V6a5 5 0 00-5-5zm-3 8V6a3 3 0 016 0v3H9zm9 2v9H6v-9h12z\"/></svg>\n </button>\n </div>\n </aside>\n\n <!-- Main Chat Area -->\n <main class=\"flex-1 flex flex-col bg-slate-50\">\n <div class=\"flex-1 overflow-y-auto p-6 space-y-4\" ref=\"messagesContainer\">\n <div v-if=\"chatMessages?.length === 0\">\n <div class=\"flex items-center w-full h-full justify-center py-3 mb-4\">\n <p class=\"mx-4 font-bold text-content\">\n Ask Mongoose Studio to analyze your data or generate a script\n </p>\n </div>\n </div>\n <ul role=\"list\" class=\"space-y-4\" v-else>\n <li v-for=\"message in chatMessages\" :key=\"message._id\">\n <chat-message :message=\"message\" :target-dashboard-id=\"currentThread?.dashboardId\"></chat-message>\n </li>\n </ul>\n </div>\n\n\n <!-- Input Area -->\n <div class=\"border-t p-4\">\n <form @submit.prevent=\"sendMessage\" :disabled=\"sendingMessage\" class=\"flex gap-2 items-end justify-end\">\n <textarea\n v-model=\"newMessage\"\n :placeholder=\"sendingMessage ? 'Sending...' : 'Ask about your data, generate a query, or build a chart…'\"\n class=\"flex-1 border rounded px-4 py-2 resize-none overflow-y-auto shadow-sm\"\n :disabled=\"sendingMessage\"\n rows=\"2\"\n ref=\"messageInput\"\n @input=\"adjustTextareaHeight\"\n @keydown.enter.exact.prevent=\"handleEnter\"\n ></textarea>\n <button class=\"bg-primary hover:bg-primary-hover text-white px-4 h-[42px] rounded disabled:bg-gray-600\" :disabled=\"sendingMessage\">\n <svg v-if=\"sendingMessage\" style=\"height: 1em\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" opacity=\"0.3\" />\n <path d=\"M12 2a10 10 0 0 1 10 10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\" />\n </path>\n </g>\n </svg>\n <span v-else>Send</span>\n </button>\n </form>\n </div>\n </main>\n\n <pro-upgrade-modal\n :show=\"showProUpgradeModal\"\n feature-description=\"Sharing threads lets you collaborate with your team by sharing chat threads within your workspace.\"\n @close=\"showProUpgradeModal = false\"\n ></pro-upgrade-modal>\n</div>\n";
|
|
50122
50788
|
|
|
50123
50789
|
/***/ },
|
|
50124
50790
|
|
|
@@ -50239,7 +50905,7 @@ module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b
|
|
|
50239
50905
|
(module) {
|
|
50240
50906
|
|
|
50241
50907
|
"use strict";
|
|
50242
|
-
module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b border-gray-100 px-2 pb-2 text-xl font-bold\">\n {{header}}\n </div>\n <div class=\"text-xl p-2\">\n {{displayValue}}\n </div>\n</div
|
|
50908
|
+
module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b border-gray-100 px-2 pb-2 text-xl font-bold\">\n {{header}}\n </div>\n <div class=\"text-xl p-2\" :class=\"displayClass\">\n {{displayValue}}\n </div>\n</div>\n";
|
|
50243
50909
|
|
|
50244
50910
|
/***/ },
|
|
50245
50911
|
|
|
@@ -50250,7 +50916,7 @@ module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b
|
|
|
50250
50916
|
(module) {
|
|
50251
50917
|
|
|
50252
50918
|
"use strict";
|
|
50253
|
-
module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=\"el in result\"
|
|
50919
|
+
module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=\"(el, index) in result\">\n <component\n class=\"bg-surface shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(el)\"\n :value=\"el\">\n </component>\n </div>\n </div>\n <div v-else>\n <component\n class=\"bg-surface shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(result)\"\n :value=\"result\"\n :fullscreen=\"fullscreen\"\n @fullscreen=\"$emit('fullscreen')\">\n </component>\n </div>\n <div class=\"text-right text-sm text-content-secondary mt-1\" v-if=\"finishedEvaluatingAt && !fullscreen\">\n Last Evaluated: {{ format.isoToLongDateTime(finishedEvaluatingAt) }}\n </div>\n</div>\n";
|
|
50254
50920
|
|
|
50255
50921
|
/***/ },
|
|
50256
50922
|
|
|
@@ -50261,7 +50927,7 @@ module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=
|
|
|
50261
50927
|
(module) {
|
|
50262
50928
|
|
|
50263
50929
|
"use strict";
|
|
50264
|
-
module.exports = "<div class=\"overflow-x-auto\">\n <table class=\"min-w-full border-separate border-spacing-0\">\n <thead v-if=\"hasColumns\" class=\"bg-slate-50\">\n <tr>\n <th\n v-for=\"(column, index) in columns\"\n :key=\"'column-' + index\"\n class=\"bg-slate-50 p-3 text-left text-sm font-semibold text-content border-b border-edge\"\n >\n {{ column }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, rowIndex) in rows\" :key=\"'row-' + rowIndex\" class=\"bg-surface hover:bg-slate-50\">\n <td\n v-for=\"(cell, columnIndex) in row\"\n :key=\"'cell-' + rowIndex + '-' + columnIndex\"\n class=\"p-3 text-sm text-content border-b border-edge\"\n >\n {{ displayValue(cell) }}\n </td>\n </tr>\n <tr v-if=\"!hasRows\">\n <td\n :colspan=\"Math.max(columns.length, 1)\"\n class=\"p-3 text-sm text-content-tertiary border-b border-edge\"\n >\n No rows\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n";
|
|
50930
|
+
module.exports = "<div class=\"overflow-x-auto\">\n <table class=\"min-w-full border-separate border-spacing-0\">\n <thead v-if=\"hasColumns\" class=\"bg-slate-50\">\n <tr>\n <th\n v-for=\"(column, index) in columns\"\n :key=\"'column-' + index\"\n class=\"bg-slate-50 p-3 text-left text-sm font-semibold text-content border-b border-edge\"\n >\n <div v-if=\"index === columns.length - 1\" class=\"relative flex items-center gap-2 w-full\" ref=\"dropdown\">\n <span class=\"min-w-0 flex-1\">{{ column }}</span>\n <button\n @click.stop=\"toggleDropdown\"\n class=\"ml-auto rounded p-1 text-content-secondary hover:bg-muted hover:text-content\"\n aria-label=\"Table actions\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n <div\n v-if=\"showDropdown\"\n class=\"absolute right-0 top-full z-10 mt-2 w-56 origin-top-right rounded-md bg-surface py-1 shadow-lg ring-1 ring-black/5\">\n <button\n class=\"block w-full text-left px-4 py-2 text-xs text-content-secondary hover:bg-muted\"\n @click=\"downloadCsv(); showDropdown = false\">\n Download as CSV\n </button>\n </div>\n </div>\n <template v-else>{{ column }}</template>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, rowIndex) in rows\" :key=\"'row-' + rowIndex\" class=\"bg-surface hover:bg-slate-50\">\n <td\n v-for=\"(cell, columnIndex) in row\"\n :key=\"'cell-' + rowIndex + '-' + columnIndex\"\n class=\"p-3 text-sm text-content border-b border-edge\"\n >\n {{ displayValue(cell) }}\n </td>\n </tr>\n <tr v-if=\"!hasRows\">\n <td\n :colspan=\"Math.max(columns.length, 1)\"\n class=\"p-3 text-sm text-content-tertiary border-b border-edge\"\n >\n No rows\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n";
|
|
50265
50931
|
|
|
50266
50932
|
/***/ },
|
|
50267
50933
|
|
|
@@ -50320,6 +50986,17 @@ module.exports = "<div class=\"w-full\">\n <div v-if=\"!arrayValue || arrayValu
|
|
|
50320
50986
|
|
|
50321
50987
|
/***/ },
|
|
50322
50988
|
|
|
50989
|
+
/***/ "./frontend/src/detail-date/detail-date.html"
|
|
50990
|
+
/*!***************************************************!*\
|
|
50991
|
+
!*** ./frontend/src/detail-date/detail-date.html ***!
|
|
50992
|
+
\***************************************************/
|
|
50993
|
+
(module) {
|
|
50994
|
+
|
|
50995
|
+
"use strict";
|
|
50996
|
+
module.exports = "<pre class=\"w-full whitespace-pre-wrap break-words font-mono text-sm text-content-secondary m-0\">{{displayValue}}</pre>\n";
|
|
50997
|
+
|
|
50998
|
+
/***/ },
|
|
50999
|
+
|
|
50323
51000
|
/***/ "./frontend/src/detail-default/detail-default.html"
|
|
50324
51001
|
/*!*********************************************************!*\
|
|
50325
51002
|
!*** ./frontend/src/detail-default/detail-default.html ***!
|
|
@@ -50331,6 +51008,17 @@ module.exports = "<div class=\"w-full\">\n <pre v-if=\"!isGeoJsonGeometry || !m
|
|
|
50331
51008
|
|
|
50332
51009
|
/***/ },
|
|
50333
51010
|
|
|
51011
|
+
/***/ "./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.html"
|
|
51012
|
+
/*!****************************************************************************************!*\
|
|
51013
|
+
!*** ./frontend/src/document-details/date-view-mode-picker/date-view-mode-picker.html ***!
|
|
51014
|
+
\****************************************************************************************/
|
|
51015
|
+
(module) {
|
|
51016
|
+
|
|
51017
|
+
"use strict";
|
|
51018
|
+
module.exports = "<div class=\"flex items-center gap-2\" @click.stop>\n <select\n :value=\"format\"\n @input=\"onFormatChange($event.target.value)\"\n class=\"text-xs border border-edge rounded-md bg-surface px-2 py-1\"\n >\n <option value=\"utc_iso\">UTC (ISO)</option>\n <option value=\"local_browser\">Local (Browser)</option>\n <option value=\"unix_ms\">Unix (ms)</option>\n <option value=\"unix_seconds\">Unix (seconds)</option>\n <option value=\"duration_relative\">Duration relative to now</option>\n <option value=\"custom_tz\">Custom TZ...</option>\n </select>\n <input\n v-if=\"format === 'custom_tz'\"\n :value=\"timezone\"\n @input=\"onTimezoneChange($event.target.value.trim())\"\n :list=\"timezoneDatalistId\"\n type=\"text\"\n placeholder=\"America/New_York\"\n class=\"text-xs border border-edge rounded-md bg-surface px-2 py-1 w-40\"\n >\n <datalist v-if=\"format === 'custom_tz'\" :id=\"timezoneDatalistId\">\n <option v-for=\"tz in timezones\" :key=\"tz\" :value=\"tz\"></option>\n </datalist>\n</div>\n";
|
|
51019
|
+
|
|
51020
|
+
/***/ },
|
|
51021
|
+
|
|
50334
51022
|
/***/ "./frontend/src/document-details/document-details.css"
|
|
50335
51023
|
/*!************************************************************!*\
|
|
50336
51024
|
!*** ./frontend/src/document-details/document-details.css ***!
|
|
@@ -50371,7 +51059,7 @@ module.exports = ".document-details {\n width: 100%;\n }\n \n .document-de
|
|
|
50371
51059
|
(module) {
|
|
50372
51060
|
|
|
50373
51061
|
"use strict";
|
|
50374
|
-
module.exports = "<div class=\"border border-edge bg-surface rounded-lg mb-2\" style=\"overflow: visible;\">\n <!-- Collapsible Header -->\n <div\n @click=\"toggleCollapse\"\n class=\"p-1 cursor-pointer flex items-center justify-between border-b border-edge transition-colors duration-200 ease-in-out\"\n :class=\"{ 'bg-amber-100 hover:bg-amber-200': highlight, 'bg-slate-100 hover:bg-muted': !highlight }\"\n style=\"overflow: visible; position: relative;\"\n >\n <div class=\"flex items-center\" >\n <svg\n :class=\"isCollapsed ? 'rotate-0' : 'rotate-90'\"\n class=\"w-4 h-4 text-content-tertiary mr-2 transition-transform duration-200\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"></path>\n </svg>\n <span class=\"font-medium text-content\">{{path.path}}</span>\n <span class=\"ml-2 text-sm text-content-tertiary\">({{(path.instance || 'unknown').toLowerCase()}})</span>\n <div v-if=\"isGeoJsonGeometry\" class=\"ml-3 inline-flex items-center gap-2\">\n <div class=\"inline-flex items-center rounded-full bg-gray-200 p-0.5 text-xs font-semibold\">\n <button\n type=\"button\"\n class=\"rounded-full px-2.5 py-0.5 transition\"\n :class=\"detailViewMode === 'text' ? 'bg-blue-600 text-white shadow' : 'text-content-secondary hover:text-content'\"\n :style=\"detailViewMode === 'text' ? 'color: white !important; background-color: #2563eb !important;' : ''\"\n @click.stop=\"setDetailViewMode('text')\">\n Text\n </button>\n <button\n type=\"button\"\n class=\"rounded-full px-2.5 py-0.5 transition\"\n :class=\"detailViewMode === 'map' ? 'bg-blue-600 text-white shadow' : 'text-content-secondary hover:text-content'\"\n :style=\"detailViewMode === 'map' ? 'color: white !important; background-color: #2563eb !important;' : ''\"\n @click.stop=\"setDetailViewMode('map')\">\n Map\n </button>\n </div>\n <!-- Info icon with tooltip -->\n <div v-if=\"editting\" class=\"relative inline-block\" style=\"z-index: 10002;\" @mouseenter=\"showTooltip = true\" @mouseleave=\"showTooltip = false\" @click.stop>\n <svg\n ref=\"infoIcon\"\n class=\"w-6 h-6 text-gray-400 hover:text-gray-600 cursor-help\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"></path>\n </svg>\n <div\n v-show=\"showTooltip\"\n ref=\"tooltip\"\n class=\"absolute left-full top-0 ml-2 w-64 p-3 text-white text-xs rounded-lg shadow-xl\"\n style=\"z-index: 99999; pointer-events: none; white-space: normal; position: fixed; background-color: #111827;\"\n :style=\"getTooltipStyle()\"\n >\n <div class=\"font-semibold mb-2\">Map Controls:</div>\n <div v-if=\"isGeoJsonPoint\" class=\"space-y-1\">\n <div>• Drag pin to move location</div>\n </div>\n <div v-else-if=\"isGeoJsonPolygon\" class=\"space-y-1\">\n <div>• Drag vertices to reshape polygon</div>\n <div v-if=\"isMultiPolygon\">• Right-click edge to add new vertex</div>\n <div>• Right-click vertex to delete</div>\n </div>\n <div class=\"absolute top-2 -left-1 w-0 h-0 border-t-4 border-b-4 border-r-4 border-transparent border-r-gray-900\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <button\n type=\"button\"\n class=\"flex items-center gap-1 text-sm text-gray-600 hover:text-gray-800 px-2 py-1 rounded-md border border-transparent hover:border-edge-strong bg-surface\"\n @click.stop.prevent=\"copyPropertyValue\"\n title=\"Copy value\"\n aria-label=\"Copy property value\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7h8m-8 4h8m-8 4h5m-7-9a2 2 0 012-2h7a2 2 0 012 2v10a2 2 0 01-2 2H8l-4-4V7a2 2 0 012-2z\" />\n </svg>\n {{copyButtonLabel}}\n </button>\n <router-link\n v-if=\"path.ref && getValueForPath(path.path)\"\n :to=\"`/model/${path.ref}/document/${getValueForPath(path.path)}`\"\n class=\"bg-primary hover:bg-primary-hover text-primary-text px-2 py-1 text-sm rounded-md\"\n @click.stop\n >View Document\n </router-link>\n </div>\n </div>\n\n <!-- Collapsible Content -->\n <div v-if=\"!isCollapsed\" class=\"p-2\">\n <!-- Date Type Selector (when editing dates) -->\n <div v-if=\"editting && path.instance === 'Date'\" class=\"mb-3 flex gap-1.5\">\n <div\n @click=\"dateType = 'picker'\"\n :class=\"dateType === 'picker' ? 'bg-teal-600' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'picker' ? 'text-white' : ''\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n Date Picker\n </div>\n </div>\n <div\n @click=\"dateType = 'iso'\"\n :class=\"dateType === 'iso' ? 'bg-teal-600' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'iso' ? 'text-white' : ''\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n ISO String\n </div>\n </div>\n </div>\n\n <!-- Field Content -->\n <div v-if=\"editting && path.path !== '_id'\">\n <!-- Use detail-default with map editing for GeoJSON geometries -->\n <component\n v-if=\"isGeoJsonGeometry\"\n :is=\"getComponentForPath(path)\"\n :value=\"getEditValueForPath(path)\"\n :view-mode=\"detailViewMode\"\n :on-change=\"handleInputChange\"\n >\n </component>\n <!-- Use standard edit components for other types -->\n <component\n v-else\n :is=\"getEditComponentForPath(path)\"\n :value=\"getEditValueForPath(path)\"\n :format=\"dateType\"\n v-bind=\"getEditComponentProps(path)\"\n @input=\"handleInputChange($event)\"\n @error=\"invalid[path.path] = $event;\"\n >\n </component>\n </div>\n <div v-else>\n <!-- Show truncated or full value based on needsTruncation and isValueExpanded -->\n <!-- Special handling for truncated arrays -->\n <div v-if=\"isArray && shouldShowTruncated\" class=\"w-full\">\n <div class=\"mt-2\">\n <div\n v-for=\"(item, index) in truncatedArrayItems\"\n :key=\"index\"\n class=\"mb-1.5 py-2.5 px-3 pl-4 bg-transparent border-l-[3px] border-l-blue-500 rounded-none transition-all duration-200 cursor-pointer relative hover:bg-slate-50 hover:border-l-blue-600\">\n <div class=\"absolute -left-2 top-1/2 -translate-y-1/2 w-5 h-5 bg-blue-500 text-white rounded-full flex items-center justify-center text-[10px] font-semibold font-mono z-10 hover:bg-blue-600\">{{ index }}</div>\n <div v-if=\"arrayUtils.isObjectItem(item)\" class=\"flex flex-col gap-1 mt-1 px-2\">\n <div\n v-for=\"key in arrayUtils.getItemKeys(item)\"\n :key=\"key\"\n class=\"flex items-start gap-2 text-xs font-mono\">\n <span class=\"font-semibold text-gray-600 flex-shrink-0 min-w-[80px]\">{{ key }}:</span>\n <span class=\"text-gray-800 break-words whitespace-pre-wrap flex-1\">{{ arrayUtils.formatItemValue(item, key) }}</span>\n </div>\n </div>\n <div v-else class=\"text-xs py-1.5 px-2 font-mono text-gray-800 break-words whitespace-pre-wrap mt-1\">{{ arrayUtils.formatValue(item) }}</div>\n </div>\n <div class=\"mb-1.5 py-2.5 px-3 pl-4 bg-transparent border-none border-l-[3px] border-l-blue-500 rounded-none transition-all duration-200 cursor-pointer relative opacity-70 hover:opacity-100\">\n <div class=\"text-xs py-1.5 px-2 font-mono text-content-tertiary italic break-words whitespace-pre-wrap mt-1\">\n ... and {{ remainingArrayCount }} more item{{ remainingArrayCount !== 1 ? 's' : '' }}\n </div>\n </div>\n </div>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show all {{ arrayValue.length }} items\n </button>\n </div>\n <!-- Non-array truncated view -->\n <div v-else-if=\"shouldShowTruncated && !isArray\" class=\"relative\">\n <div class=\"text-content-secondary whitespace-pre-wrap break-words font-mono text-sm\">{{truncatedString}}</div>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show more ({{valueAsString.length}} characters)\n </button>\n </div>\n <!-- Expanded view -->\n <div v-else-if=\"needsTruncation && isValueExpanded\" class=\"relative\">\n <component\n :is=\"getComponentForPath(path)\"\n :value=\"getValueForPath(path.path)\"\n :view-mode=\"detailViewMode\"></component>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4 rotate-180\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show less\n </button>\n </div>\n <!-- Full view (no truncation needed) -->\n <div v-else>\n <component\n :is=\"getComponentForPath(path)\"\n :value=\"getValueForPath(path.path)\"\n :view-mode=\"detailViewMode\"></component>\n </div>\n </div>\n </div>\n</div>\n";
|
|
51062
|
+
module.exports = "<div class=\"border border-edge bg-surface rounded-lg mb-2\" style=\"overflow: visible;\">\n <!-- Collapsible Header -->\n <div\n @click=\"toggleCollapse\"\n class=\"p-1 cursor-pointer flex items-center justify-between border-b border-edge transition-colors duration-200 ease-in-out\"\n :class=\"{ 'bg-amber-100 hover:bg-amber-200': highlight, 'bg-slate-100 hover:bg-muted': !highlight }\"\n style=\"overflow: visible; position: relative;\"\n >\n <div class=\"flex items-center\" >\n <svg\n :class=\"isCollapsed ? 'rotate-0' : 'rotate-90'\"\n class=\"w-4 h-4 text-content-tertiary mr-2 transition-transform duration-200\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"></path>\n </svg>\n <span class=\"font-medium text-content\">{{path.path}}</span>\n <span class=\"ml-2 text-sm text-content-tertiary\">({{(path.instance || 'unknown').toLowerCase()}})</span>\n <div v-if=\"isGeoJsonGeometry\" class=\"ml-3 inline-flex items-center gap-2\">\n <div class=\"inline-flex items-center rounded-full bg-gray-200 p-0.5 text-xs font-semibold\">\n <button\n type=\"button\"\n class=\"rounded-full px-2.5 py-0.5 transition\"\n :class=\"detailViewMode === 'text' ? 'bg-blue-600 text-white shadow' : 'text-content-secondary hover:text-content'\"\n :style=\"detailViewMode === 'text' ? 'color: white !important; background-color: #2563eb !important;' : ''\"\n @click.stop=\"setDetailViewMode('text')\">\n Text\n </button>\n <button\n type=\"button\"\n class=\"rounded-full px-2.5 py-0.5 transition\"\n :class=\"detailViewMode === 'map' ? 'bg-blue-600 text-white shadow' : 'text-content-secondary hover:text-content'\"\n :style=\"detailViewMode === 'map' ? 'color: white !important; background-color: #2563eb !important;' : ''\"\n @click.stop=\"setDetailViewMode('map')\">\n Map\n </button>\n </div>\n <!-- Info icon with tooltip -->\n <div v-if=\"editting\" class=\"relative inline-block\" style=\"z-index: 10002;\" @mouseenter=\"showTooltip = true\" @mouseleave=\"showTooltip = false\" @click.stop>\n <svg\n ref=\"infoIcon\"\n class=\"w-6 h-6 text-gray-400 hover:text-gray-600 cursor-help\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"></path>\n </svg>\n <div\n v-show=\"showTooltip\"\n ref=\"tooltip\"\n class=\"absolute left-full top-0 ml-2 w-64 p-3 text-white text-xs rounded-lg shadow-xl\"\n style=\"z-index: 99999; pointer-events: none; white-space: normal; position: fixed; background-color: #111827;\"\n :style=\"getTooltipStyle()\"\n >\n <div class=\"font-semibold mb-2\">Map Controls:</div>\n <div v-if=\"isGeoJsonPoint\" class=\"space-y-1\">\n <div>• Drag pin to move location</div>\n </div>\n <div v-else-if=\"isGeoJsonPolygon\" class=\"space-y-1\">\n <div>• Drag vertices to reshape polygon</div>\n <div v-if=\"isMultiPolygon\">• Right-click edge to add new vertex</div>\n <div>• Right-click vertex to delete</div>\n </div>\n <div class=\"absolute top-2 -left-1 w-0 h-0 border-t-4 border-b-4 border-r-4 border-transparent border-r-gray-900\"></div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"flex items-center gap-2\">\n <date-view-mode-picker\n v-if=\"isDatePath\"\n :viewMode=\"dateViewMode\"\n :path=\"path\"\n @update:viewMode=\"dateViewMode = $event\"\n ></date-view-mode-picker>\n <button\n type=\"button\"\n class=\"flex items-center gap-1 text-sm text-gray-600 hover:text-gray-800 px-2 py-1 rounded-md border border-transparent hover:border-edge-strong bg-surface\"\n @click.stop.prevent=\"copyPropertyValue\"\n title=\"Copy value\"\n aria-label=\"Copy property value\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7h8m-8 4h8m-8 4h5m-7-9a2 2 0 012-2h7a2 2 0 012 2v10a2 2 0 01-2 2H8l-4-4V7a2 2 0 012-2z\" />\n </svg>\n {{copyButtonLabel}}\n </button>\n <router-link\n v-if=\"path.ref && getValueForPath(path.path)\"\n :to=\"`/model/${path.ref}/document/${getValueForPath(path.path)}`\"\n class=\"bg-primary hover:bg-primary-hover text-primary-text px-2 py-1 text-sm rounded-md\"\n @click.stop\n >View Document\n </router-link>\n </div>\n </div>\n\n <!-- Collapsible Content -->\n <div v-if=\"!isCollapsed\" class=\"p-2\">\n <!-- Date Type Selector (when editing dates) -->\n <div v-if=\"editting && path.instance === 'Date'\" class=\"mb-3 flex gap-1.5\">\n <div\n @click=\"dateType = 'picker'\"\n :class=\"dateType === 'picker' ? 'bg-teal-600' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'picker' ? 'text-white' : ''\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n Date Picker\n </div>\n </div>\n <div\n @click=\"dateType = 'iso'\"\n :class=\"dateType === 'iso' ? 'bg-teal-600' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'iso' ? 'text-white' : ''\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n ISO String\n </div>\n </div>\n </div>\n\n <!-- Field Content -->\n <div v-if=\"editting && path.path !== '_id'\">\n <!-- Use detail-default with map editing for GeoJSON geometries -->\n <component\n v-if=\"isGeoJsonGeometry\"\n :is=\"getComponentForPath(path)\"\n :value=\"getEditValueForPath(path)\"\n :viewMode=\"detailViewMode\"\n :on-change=\"handleInputChange\"\n >\n </component>\n <!-- Use standard edit components for other types -->\n <component\n v-else\n :is=\"getEditComponentForPath(path)\"\n :value=\"getEditValueForPath(path)\"\n :format=\"dateType\"\n v-bind=\"getEditComponentProps(path)\"\n @input=\"handleInputChange($event)\"\n @error=\"invalid[path.path] = $event;\"\n >\n </component>\n </div>\n <div v-else>\n <!-- Show truncated or full value based on needsTruncation and isValueExpanded -->\n <!-- Special handling for truncated arrays -->\n <div v-if=\"isArray && shouldShowTruncated\" class=\"w-full\">\n <div class=\"mt-2\">\n <div\n v-for=\"(item, index) in truncatedArrayItems\"\n :key=\"index\"\n class=\"mb-1.5 py-2.5 px-3 pl-4 bg-transparent border-l-[3px] border-l-blue-500 rounded-none transition-all duration-200 cursor-pointer relative hover:bg-slate-50 hover:border-l-blue-600\">\n <div class=\"absolute -left-2 top-1/2 -translate-y-1/2 w-5 h-5 bg-blue-500 text-white rounded-full flex items-center justify-center text-[10px] font-semibold font-mono z-10 hover:bg-blue-600\">{{ index }}</div>\n <div v-if=\"arrayUtils.isObjectItem(item)\" class=\"flex flex-col gap-1 mt-1 px-2\">\n <div\n v-for=\"key in arrayUtils.getItemKeys(item)\"\n :key=\"key\"\n class=\"flex items-start gap-2 text-xs font-mono\">\n <span class=\"font-semibold text-gray-600 flex-shrink-0 min-w-[80px]\">{{ key }}:</span>\n <span class=\"text-gray-800 break-words whitespace-pre-wrap flex-1\">{{ arrayUtils.formatItemValue(item, key) }}</span>\n </div>\n </div>\n <div v-else class=\"text-xs py-1.5 px-2 font-mono text-gray-800 break-words whitespace-pre-wrap mt-1\">{{ arrayUtils.formatValue(item) }}</div>\n </div>\n <div class=\"mb-1.5 py-2.5 px-3 pl-4 bg-transparent border-none border-l-[3px] border-l-blue-500 rounded-none transition-all duration-200 cursor-pointer relative opacity-70 hover:opacity-100\">\n <div class=\"text-xs py-1.5 px-2 font-mono text-content-tertiary italic break-words whitespace-pre-wrap mt-1\">\n ... and {{ remainingArrayCount }} more item{{ remainingArrayCount !== 1 ? 's' : '' }}\n </div>\n </div>\n </div>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show all {{ arrayValue.length }} items\n </button>\n </div>\n <!-- Non-array truncated view -->\n <div v-else-if=\"shouldShowTruncated && !isArray\" class=\"relative\">\n <div class=\"text-content-secondary whitespace-pre-wrap break-words font-mono text-sm\">{{truncatedString}}</div>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show more ({{valueAsString.length}} characters)\n </button>\n </div>\n <!-- Expanded view -->\n <div v-else-if=\"needsTruncation && isValueExpanded\" class=\"relative\">\n <component\n :is=\"getComponentForPath(path)\"\n :value=\"rawValue\"\n :viewMode=\"isDatePath ? dateViewMode : detailViewMode\"\n @updated=\"renderedValue = $event\"></component>\n <button\n @click=\"toggleValueExpansion\"\n class=\"mt-2 text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center gap-1 transform transition-all duration-200 ease-in-out hover:translate-x-0.5\"\n >\n <svg class=\"w-4 h-4 rotate-180\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M19 9l-7 7-7-7\"></path>\n </svg>\n Show less\n </button>\n </div>\n <!-- Full view (no truncation needed) -->\n <div v-else>\n <component\n :is=\"getComponentForPath(path)\"\n :value=\"rawValue\"\n :viewMode=\"isDatePath ? dateViewMode : detailViewMode\"\n @updated=\"renderedValue = $event\"></component>\n </div>\n </div>\n </div>\n</div>\n";
|
|
50375
51063
|
|
|
50376
51064
|
/***/ },
|
|
50377
51065
|
|
|
@@ -50734,7 +51422,7 @@ module.exports = ".models {\n position: relative;\n display: flex;\n flex-dir
|
|
|
50734
51422
|
(module) {
|
|
50735
51423
|
|
|
50736
51424
|
"use strict";
|
|
50737
|
-
module.exports = "<div class=\"models flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <aside class=\"bg-page border-r overflow-hidden transition-all duration-300 ease-in-out z-20 w-0 lg:w-64 fixed lg:relative shrink-0 flex flex-col top-[55px] bottom-0 lg:top-auto lg:bottom-auto lg:h-full\" :class=\"hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''\">\n <!-- Search -->\n <div class=\"p-3 shrink-0\">\n <div class=\"relative\">\n <svg class=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n <input\n v-model=\"modelSearch\"\n type=\"text\"\n placeholder=\"Find model...\"\n @keydown.esc=\"modelSearch = ''\"\n class=\"w-full rounded-md border border-edge bg-surface py-1.5 pl-8 pr-3 text-sm text-content placeholder:text-gray-400 focus:border-edge-strong focus:outline-none focus:ring-1 focus:ring-gray-300\"\n />\n </div>\n </div>\n <!-- Model list (scrollable) -->\n <nav class=\"flex-1 overflow-y-auto px-2 pb-2\">\n <!-- Recently Viewed -->\n <div v-if=\"filteredRecentModels.length > 0 && !modelSearch.trim()\">\n <div class=\"px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider\">Recently Viewed</div>\n <ul role=\"list\">\n <li v-for=\"model in filteredRecentModels\" :key=\"'recent-' + model\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary\"\n :class=\"model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'\">\n <span class=\"truncate\" v-html=\"highlightMatch(model)\"></span>\n <span\n v-if=\"modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel\"\n class=\"ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]\"\n >\n {{formatCompactCount(modelDocumentCounts[model])}}\n </span>\n </router-link>\n </li>\n </ul>\n <div class=\"border-b border-edge my-2\"></div>\n </div>\n <!-- All Models / Search Results -->\n <div class=\"px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider\">{{ modelSearch.trim() ? 'Search Results' : 'All Models' }}</div>\n <ul role=\"list\">\n <li v-for=\"model in filteredModels\" :key=\"'all-' + model\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary\"\n :class=\"model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'\">\n <span class=\"truncate\" v-html=\"highlightMatch(model)\"></span>\n <span\n v-if=\"modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel\"\n class=\"ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]\"\n >\n {{formatCompactCount(modelDocumentCounts[model])}}\n </span>\n </router-link>\n </li>\n </ul>\n <div v-if=\"filteredModels.length === 0 && modelSearch.trim()\" class=\"px-2 py-2 text-sm text-content-tertiary\">\n No models match \"{{modelSearch}}\"\n </div>\n <div v-if=\"models.length === 0 && status === 'loaded'\" class=\"p-2 bg-red-100 rounded-md\">\n No models found\n </div>\n </nav>\n <!-- Bottom toolbar -->\n <div class=\"shrink-0 border-t border-edge bg-page px-2 py-1.5 flex items-center gap-1\">\n <button\n type=\"button\"\n @click=\"hideSidebar = true\"\n class=\"rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n title=\"Hide sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5\" />\n </svg>\n </button>\n <button\n type=\"button\"\n @click=\"openModelSwitcher\"\n class=\"rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n title=\"Quick switch (Ctrl+P)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n </button>\n </div>\n </aside>\n <div class=\"documents bg-slate-50 min-w-0\" ref=\"documentsList\">\n <div class=\"documents-menu bg-slate-50\">\n <div class=\"flex flex-row items-center w-full gap-2\">\n <button\n v-if=\"hideSidebar === true || hideSidebar === null\"\n type=\"button\"\n @click=\"hideSidebar = false\"\n class=\"shrink-0 rounded-md p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n :class=\"hideSidebar === null ? 'lg:hidden' : ''\"\n title=\"Show sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n <document-search\n ref=\"documentSearch\"\n :value=\"searchText\"\n :schema-paths=\"schemaPaths\"\n @search=\"search\"\n >\n </document-search>\n <div>\n <span v-if=\"numDocuments == null\">Loading ...</span>\n <span v-else-if=\"typeof numDocuments === 'number'\">{{documents.length}}/{{numDocuments === 1 ? numDocuments + ' document' : numDocuments + ' documents'}}</span>\n </div>\n <button\n @click=\"stagingSelect\"\n type=\"button\"\n :class=\"{\n 'bg-page0 ring-inset ring-2 ring-gray-300 hover:bg-gray-200 text-content-secondary': selectMultiple,\n 'bg-primary hover:bg-primary-hover text-primary-text': !selectMultiple\n }\"\n class=\"rounded px-2 py-2 text-sm font-semibold shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {{ selectMultiple ? 'Cancel' : 'Select' }}\n </button>\n <button\n v-show=\"selectMultiple\"\n @click=\"shouldShowUpdateMultipleModal=true;\"\n type=\"button\"\n class=\"rounded bg-green-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600\"\n >\n Update\n </button>\n <button\n @click=\"shouldShowDeleteMultipleModal=true;\"\n type=\"button\"\n v-show=\"selectMultiple\"\n class=\"rounded bg-red-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500\"\n >\n Delete\n </button>\n <div class=\"relative\" v-show=\"!selectMultiple\" ref=\"actionsMenuContainer\" @keyup.esc.prevent=\"closeActionsMenu\">\n <button\n @click=\"toggleActionsMenu\"\n type=\"button\"\n aria-label=\"More actions\"\n class=\"rounded bg-surface px-2 py-2 text-sm font-semibold text-content-secondary shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-page focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z\" />\n </svg>\n </button>\n <div\n v-if=\"showActionsMenu\"\n class=\"absolute right-0 mt-2 w-48 origin-top-right rounded-md bg-surface shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-50\"\n >\n <div class=\"py-1\">\n <button\n @click=\"shouldShowExportModal = true; showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Export\n </button>\n <button\n @click=\"shouldShowCreateModal = true; showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Create\n </button>\n <button\n @click=\"openIndexModal\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Indexes\n </button>\n <button\n @click=\"openCollectionInfo\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Collection Info\n </button>\n <button\n @click=\"findOldestDocument\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Find oldest document\n </button>\n <button\n @click=\"toggleRowNumbers()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n {{ showRowNumbers ? 'Hide row numbers' : 'Show row numbers' }}\n </button>\n <button\n @click=\"resetFilter()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Reset Filter\n </button>\n <button\n @click=\"toggleProjectionMenu(); showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm hover:bg-muted\"\n :class=\"isProjectionMenuSelected ? 'text-primary font-semibold' : 'text-content-secondary'\"\n >\n {{ isProjectionMenuSelected ? 'Projection (On)' : 'Projection' }}\n </button>\n <button\n v-if=\"isProjectionMenuSelected\"\n @click=\"clearProjection()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Reset Projection\n </button>\n <async-button\n v-if=\"isProjectionMenuSelected\"\n type=\"button\"\n @click=\"applyDefaultProjectionColumns()\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Default Projection\n </async-button>\n </div>\n </div>\n </div>\n <span class=\"isolate inline-flex rounded-md shadow-sm\">\n <button\n @click=\"setOutputType('table')\"\n type=\"button\"\n class=\"relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10\"\n :class=\"outputType === 'table' ? 'bg-gray-200' : 'bg-surface'\">\n <img class=\"h-5 w-5\" src=\"images/table.svg\">\n </button>\n <button\n @click=\"setOutputType('json')\"\n type=\"button\"\n class=\"relative -ml-px inline-flex items-center px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10\"\n :class=\"outputType === 'json' ? 'bg-gray-200' : 'bg-surface'\">\n <img class=\"h-5 w-5\" src=\"images/json.svg\">\n </button>\n <button\n @click=\"setOutputType('map')\"\n :disabled=\"geoJsonFields.length === 0\"\n type=\"button\"\n :title=\"geoJsonFields.length > 0 ? 'Map view' : 'No GeoJSON fields detected'\"\n class=\"relative -ml-px inline-flex items-center rounded-none rounded-r-md px-2 py-2 ring-1 ring-inset ring-gray-300 focus:z-10\"\n :class=\"[\n geoJsonFields.length === 0 ? 'text-gray-300 cursor-not-allowed bg-muted' : 'text-gray-400 hover:bg-page',\n outputType === 'map' ? 'bg-gray-200' : (geoJsonFields.length > 0 ? 'bg-surface' : '')\n ]\">\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 6.75V15m6-6v8.25m.503 3.498 4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 0 0-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0Z\" />\n </svg>\n </button>\n </span>\n </div>\n <div v-if=\"isProjectionMenuSelected && (outputType === 'table' || outputType === 'json')\" class=\"flex items-center gap-2 w-full mt-2 flex-shrink-0\">\n <input\n ref=\"projectionInput\"\n v-model=\"projectionText\"\n type=\"text\"\n placeholder=\"Projection: name email, or -password\"\n class=\"flex-1 min-w-0 rounded border border-edge bg-surface px-2 py-1.5 text-sm font-mono placeholder:text-content-tertiary focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n @focus=\"initProjection($event)\"\n @keydown.enter=\"applyProjectionFromInput()\"\n />\n </div>\n </div>\n <!-- In JSON view, this container is the scrollable element used for infinite scroll. -->\n <div class=\"documents-container relative\" ref=\"documentsContainerScroll\" @scroll=\"checkIfScrolledToBottom\">\n <div v-if=\"error\">\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 relative m-4 rounded-md\" role=\"alert\">\n <span class=\"block font-bold\">Error</span>\n <span class=\"block\">{{ error }}</span>\n </div>\n </div>\n <div v-else-if=\"outputType === 'table'\" class=\"flex-1 min-h-0 flex flex-col overflow-hidden\">\n <div\n ref=\"documentsScrollContainer\"\n class=\"overflow-x-auto overflow-y-auto flex-1 min-h-0 border border-edge rounded-lg bg-surface\"\n @scroll=\"checkIfScrolledToBottom\"\n >\n <table class=\"min-w-full border-collapse text-sm\">\n <thead class=\"sticky top-0 z-10 bg-slate-100 dark:bg-shark-800 border-b border-edge\">\n <tr>\n <th v-if=\"showRowNumbers\" class=\"px-3 py-2.5 text-left font-medium text-content border-r border-edge whitespace-nowrap align-middle w-0\">\n #\n </th>\n <th\n v-for=\"path in tableDisplayPaths\"\n :key=\"path.path\"\n class=\"px-3 py-2.5 text-left font-medium text-content border-r border-edge last:border-r-0 whitespace-nowrap align-middle\"\n >\n <div class=\"flex items-center gap-2\">\n <span\n @click=\"addPathFilter(path.path)\"\n class=\"cursor-pointer hover:text-primary truncate min-w-0\"\n :title=\"path.path\"\n >\n {{ path.path }}\n </span>\n <span class=\"text-xs text-content-tertiary shrink-0\">({{ path.instance || 'unknown' }})</span>\n <span class=\"inline-flex shrink-0 gap-0.5 items-center\">\n <button\n type=\"button\"\n @click.stop=\"sortDocs(1, path.path)\"\n class=\"p-0.5 rounded text-content-tertiary hover:text-content hover:bg-muted\"\n :class=\"{ 'text-primary font-semibold': sortBy[path.path] === 1 }\"\n :title=\"sortBy[path.path] === 1 ? 'Clear sort' : 'Sort ascending'\"\n >\n ↑\n </button>\n <button\n type=\"button\"\n @click.stop=\"sortDocs(-1, path.path)\"\n class=\"p-0.5 rounded text-content-tertiary hover:text-content hover:bg-muted\"\n :class=\"{ 'text-primary font-semibold': sortBy[path.path] === -1 }\"\n :title=\"sortBy[path.path] === -1 ? 'Clear sort' : 'Sort descending'\"\n >\n ↓\n </button>\n <button\n v-if=\"filteredPaths.length > 0\"\n type=\"button\"\n @click.stop=\"removeField(path)\"\n class=\"p-1.5 rounded-md border border-transparent text-content-tertiary hover:text-valencia-600 hover:bg-valencia-50 hover:border-valencia-200 focus:outline-none focus:ring-2 focus:ring-valencia-500/30\"\n title=\"Remove column\"\n aria-label=\"Remove column\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </span>\n </div>\n </th>\n <th v-if=\"filteredPaths.length > 0\" class=\"px-2 py-2.5 border-r border-edge last:border-r-0 align-middle w-0 bg-slate-50 dark:bg-shark-800/80\">\n <div class=\"relative\" ref=\"addFieldContainer\">\n <button\n type=\"button\"\n @click=\"toggleAddFieldDropdown()\"\n class=\"flex items-center justify-center w-8 h-8 rounded border border-dashed border-edge text-content-tertiary hover:border-primary hover:text-primary hover:bg-primary-subtle/30\"\n title=\"Add column\"\n aria-label=\"Add column\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" class=\"w-5 h-5\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /> </svg>\n </button>\n <div\n v-if=\"showAddFieldDropdown\"\n class=\"absolute right-0 top-full mt-1 z-[100] min-w-[180px] max-w-[280px] rounded-md border border-edge bg-surface shadow-lg py-1 max-h-48 overflow-y-auto\"\n >\n <input\n v-if=\"availablePathsToAdd.length > 5\"\n ref=\"addFieldFilterInput\"\n v-model=\"addFieldFilterText\"\n type=\"text\"\n placeholder=\"Filter fields...\"\n class=\"mx-2 mb-1 w-[calc(100%-1rem)] rounded border border-edge px-2 py-1 text-sm\"\n @click.stop\n />\n <button\n v-for=\"p in filteredPathsToAdd\"\n :key=\"p.path\"\n type=\"button\"\n class=\"w-full px-3 py-1.5 text-left text-sm hover:bg-muted\"\n @click.stop=\"addField(p)\"\n >\n {{ p.path }}\n </button>\n <p v-if=\"filteredPathsToAdd.length === 0\" class=\"px-3 py-2 text-sm text-content-tertiary\">\n {{ addFieldFilterText.trim() ? 'No matching fields' : 'All fields added' }}\n </p>\n </div>\n </div>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-surface\">\n <tr\n v-for=\"(document, docIndex) in documents\"\n :key=\"document._id\"\n @click=\"handleDocumentClick(document, $event)\"\n class=\"border-b border-edge cursor-pointer transition-colors hover:bg-muted/60\"\n :class=\"{ 'bg-primary-subtle/50 hover:bg-primary-subtle/70': selectedDocuments.some(x => x._id.toString() === document._id.toString()) }\"\n >\n <td v-if=\"showRowNumbers\" class=\"px-3 py-2 border-r border-edge align-top text-content-tertiary whitespace-nowrap\">\n {{ docIndex + 1 }}\n </td>\n <td\n v-for=\"schemaPath in tableDisplayPaths\"\n :key=\"schemaPath.path\"\n class=\"px-3 py-2 border-r border-edge last:border-r-0 align-top max-w-[280px]\"\n >\n <div class=\"table-cell-content flex items-center gap-1.5 min-w-0 group\">\n <span class=\"min-w-0 overflow-hidden text-ellipsis flex-1\">\n <component\n :is=\"getComponentForPath(schemaPath)\"\n :value=\"getValueForPath(document, schemaPath.path)\"\n :allude=\"getReferenceModel(schemaPath)\"\n />\n </span>\n <button\n type=\"button\"\n class=\"table-cell-copy shrink-0 p-1 rounded text-content-tertiary hover:text-content hover:bg-muted focus:outline-none focus:ring-1 focus:ring-edge\"\n aria-label=\"Copy cell value\"\n @click.stop=\"copyCellValue(getValueForPath(document, schemaPath.path))\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 5H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1M8 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M8 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m0 0h2a2 2 0 0 1 2 2v3m2 4H10m0 0l3-3m-3 3l3 3\" />\n </svg>\n </button>\n </div>\n </td>\n <td v-if=\"filteredPaths.length > 0\" class=\"w-0 px-0 py-0 border-r border-edge last:border-r-0 bg-slate-50/50 dark:bg-shark-800/30\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n <div v-if=\"outputType === 'table' && (loadingMore || (status === 'loading' && documents.length > 0))\" class=\"flex items-center justify-center gap-2 py-3 text-sm text-content-tertiary border-t border-edge bg-surface\">\n <img src=\"images/loader.gif\" alt=\"\" class=\"h-5 w-5\">\n <span>Loading documents…</span>\n </div>\n <p v-if=\"outputType === 'table' && documents.length === 0 && status === 'loaded'\" class=\"mt-2 text-sm text-content-tertiary px-1\">\n No documents to show. Use Projection in the menu to choose columns.\n </p>\n </div>\n <div v-else-if=\"outputType === 'json'\" class=\"flex flex-col space-y-2 p-1 mt-1\">\n <div\n v-for=\"document in documents\"\n :key=\"document._id\"\n @click=\"handleDocumentContainerClick(document, $event)\"\n :class=\"[\n 'group relative transition-colors rounded-md border border-slate-100',\n selectedDocuments.some(x => x._id.toString() === document._id.toString()) ? 'bg-blue-200' : 'hover:shadow-sm hover:border-slate-300 bg-surface'\n ]\"\n >\n <button\n type=\"button\"\n class=\"absolute top-2 right-2 z-10 inline-flex items-center rounded bg-primary px-2 py-1 text-xs font-semibold text-primary-text shadow-sm transition-opacity duration-150 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n @click.stop=\"openDocument(document)\"\n >\n Open this Document\n </button>\n <list-json :value=\"filterDocument(document)\" :references=\"referenceMap\">\n </list-json>\n </div>\n <div v-if=\"outputType === 'json' && (loadingMore || (status === 'loading' && documents.length > 0))\" class=\"flex items-center justify-center gap-2 py-3 text-sm text-content-tertiary\">\n <img src=\"images/loader.gif\" alt=\"\" class=\"h-5 w-5\">\n <span>Loading documents…</span>\n </div>\n </div>\n <div v-else-if=\"outputType === 'map'\" class=\"flex flex-col h-full\">\n <div class=\"p-2 bg-surface border-b flex items-center gap-2\">\n <label class=\"text-sm font-medium text-content-secondary\">GeoJSON Field:</label>\n <select\n :value=\"selectedGeoField\"\n @change=\"setSelectedGeoField($event.target.value)\"\n class=\"rounded-md border border-edge-strong py-1 px-2 text-sm focus:border-primary focus:ring-primary\"\n >\n <option v-for=\"field in geoJsonFields\" :key=\"field.path\" :value=\"field.path\">\n {{ field.label }}\n </option>\n </select>\n <async-button\n @click=\"loadMoreDocuments\"\n :disabled=\"loadedAllDocs\"\n type=\"button\"\n class=\"rounded px-2 py-1 text-xs font-semibold text-primary-text shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n :class=\"loadedAllDocs ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary hover:bg-primary-hover'\"\n >\n Load more\n </async-button>\n </div>\n <div class=\"flex-1 min-h-[400px]\" ref=\"modelsMap\"></div>\n </div>\n <div v-if=\"status === 'loading' && !loadingMore && documents.length === 0\" class=\"loader loader-overlay\" aria-busy=\"true\">\n <img src=\"images/loader.gif\" alt=\"Loading\">\n </div>\n </div>\n </div>\n <modal v-if=\"shouldShowExportModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowExportModal = false\">×</div>\n <export-query-results\n :schemaPaths=\"schemaPaths\"\n :search-text=\"searchText\"\n :currentModel=\"currentModel\"\n @done=\"shouldShowExportModal = false\">\n </export-query-results>\n </template>\n </modal>\n <modal v-if=\"shouldShowIndexModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowIndexModal = false\">×</div>\n <div class=\"text-xl font-bold mb-2\">Indexes</div>\n <div v-for=\"index in mongoDBIndexes\" class=\"w-full flex items-center\">\n <div class=\"grow shrink text-left flex justify-between items-center\" v-if=\"index.name != '_id_'\">\n <div>\n <div class=\"font-bold flex items-center gap-2\">\n <div>{{ index.name }}</div>\n <div v-if=\"isTTLIndex(index)\" class=\"rounded-full bg-primary-subtle px-2 py-0.5 text-xs font-semibold text-primary\">\n TTL: {{ formatTTL(index.expireAfterSeconds) }}\n </div>\n </div>\n <div class=\"text-sm font-mono\">{{ JSON.stringify(index.key) }}</div>\n </div>\n <div>\n <async-button\n type=\"button\"\n @click=\"dropIndex(index.name)\"\n class=\"rounded-md bg-valencia-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-valencia-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600 disabled:bg-gray-400 disabled:cursor-not-allowed\">\n Drop\n </async-button>\n </div>\n </div>\n </div>\n </template>\n </modal>\n <modal v-if=\"shouldShowCollectionInfoModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowCollectionInfoModal = false\">×</div>\n <div class=\"text-xl font-bold mb-2\">Collection Info</div>\n <div v-if=\"!collectionInfo\" class=\"text-gray-600\">Loading collection details...</div>\n <div v-else class=\"space-y-3\">\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Documents</div>\n <div class=\"text-content\">{{ formatNumber(collectionInfo.documentCount) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Indexes</div>\n <div class=\"text-content\">{{ formatNumber(collectionInfo.indexCount) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Total Index Size</div>\n <div class=\"text-content\">{{ formatCollectionSize(collectionInfo.totalIndexSize) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Total Storage Size</div>\n <div class=\"text-content\">{{ formatCollectionSize(collectionInfo.size) }}</div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Collation</div>\n <div class=\"text-content\">{{ collectionInfo.hasCollation ? 'Yes' : 'No' }}</div>\n </div>\n <div v-if=\"collectionInfo.hasCollation\" class=\"rounded bg-muted p-3 text-sm text-gray-800 overflow-x-auto\">\n <pre class=\"whitespace-pre-wrap\">{{ JSON.stringify(collectionInfo.collation, null, 2) }}</pre>\n </div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Capped</div>\n <div class=\"text-content\">{{ collectionInfo.capped ? 'Yes' : 'No' }}</div>\n </div>\n </div>\n </template>\n </modal>\n <modal v-if=\"shouldShowCreateModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowCreateModal = false;\">×</div>\n <create-document :currentModel=\"currentModel\" :paths=\"schemaPaths\" @close=\"closeCreationModal\"></create-document>\n </template>\n </modal>\n <modal v-if=\"shouldShowUpdateMultipleModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowUpdateMultipleModal = false;\">×</div>\n <update-document :currentModel=\"currentModel\" :document=\"selectedDocuments\" :multiple=\"true\" @update=\"updateDocuments\" @close=\"shouldShowUpdateMultipleModal=false;\"></update-document>\n </template>\n </modal>\n <modal v-if=\"shouldShowDeleteMultipleModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowDeleteMultipleModal = false;\">×</div>\n <h2>Are you sure you want to delete {{selectedDocuments.length}} documents?</h2>\n <div>\n <list-json :value=\"selectedDocuments\"></list-json>\n </div>\n <div class=\"flex gap-4\">\n <async-button @click=\"deleteDocuments\" class=\"rounded bg-red-500 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600\">\n Confirm\n </async-button>\n <button @click=\"shouldShowDeleteMultipleModal = false;\" class=\"rounded bg-gray-400 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-page0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500\">\n Cancel\n </button>\n </div>\n </template>\n </modal>\n <model-switcher\n :show=\"showModelSwitcher\"\n :models=\"models\"\n :recently-viewed-models=\"recentlyViewedModels\"\n :model-document-counts=\"modelDocumentCounts\"\n @close=\"showModelSwitcher = false\"\n @select=\"selectSwitcherModel\"\n ></model-switcher>\n</div>\n";
|
|
51425
|
+
module.exports = "<div class=\"models flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <aside class=\"bg-page border-r overflow-hidden transition-all duration-300 ease-in-out z-20 w-0 lg:w-64 fixed lg:relative shrink-0 flex flex-col top-[55px] bottom-0 lg:top-auto lg:bottom-auto lg:h-full\" :class=\"hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''\">\n <!-- Search -->\n <div class=\"p-3 shrink-0\">\n <div class=\"relative\">\n <svg class=\"absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n <input\n v-model=\"modelSearch\"\n type=\"text\"\n placeholder=\"Find model...\"\n @keydown.esc=\"modelSearch = ''\"\n class=\"w-full rounded-md border border-edge bg-surface py-1.5 pl-8 pr-3 text-sm text-content placeholder:text-gray-400 focus:border-edge-strong focus:outline-none focus:ring-1 focus:ring-gray-300\"\n />\n </div>\n </div>\n <!-- Model list (scrollable) -->\n <nav class=\"flex-1 overflow-y-auto px-2 pb-2\">\n <!-- Recently Viewed -->\n <div v-if=\"filteredRecentModels.length > 0 && !modelSearch.trim()\">\n <div class=\"px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider\">Recently Viewed</div>\n <ul role=\"list\">\n <li v-for=\"model in filteredRecentModels\" :key=\"'recent-' + model\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary\"\n :class=\"model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'\">\n <span class=\"truncate\" v-html=\"highlightMatch(model)\"></span>\n <span\n v-if=\"modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel\"\n class=\"ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]\"\n >\n {{formatCompactCount(modelDocumentCounts[model])}}\n </span>\n </router-link>\n </li>\n </ul>\n <div class=\"border-b border-edge my-2\"></div>\n </div>\n <!-- All Models / Search Results -->\n <div class=\"px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider\">{{ modelSearch.trim() ? 'Search Results' : 'All Models' }}</div>\n <ul role=\"list\">\n <li v-for=\"model in filteredModels\" :key=\"'all-' + model\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary\"\n :class=\"model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'\">\n <span class=\"truncate\" v-html=\"highlightMatch(model)\"></span>\n <span\n v-if=\"modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel\"\n class=\"ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]\"\n >\n {{formatCompactCount(modelDocumentCounts[model])}}\n </span>\n </router-link>\n </li>\n </ul>\n <div v-if=\"filteredModels.length === 0 && modelSearch.trim()\" class=\"px-2 py-2 text-sm text-content-tertiary\">\n No models match \"{{modelSearch}}\"\n </div>\n <div v-if=\"models.length === 0 && status === 'loaded'\" class=\"p-2 bg-red-100 rounded-md\">\n No models found\n </div>\n </nav>\n <!-- Bottom toolbar -->\n <div class=\"shrink-0 border-t border-edge bg-page px-2 py-1.5 flex items-center gap-1\">\n <button\n type=\"button\"\n @click=\"hideSidebar = true\"\n class=\"rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n title=\"Hide sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5\" />\n </svg>\n </button>\n <button\n type=\"button\"\n @click=\"openModelSwitcher\"\n class=\"rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n title=\"Quick switch (Ctrl+P)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z\" />\n </svg>\n </button>\n </div>\n </aside>\n <div class=\"documents bg-slate-50 min-w-0\" ref=\"documentsList\">\n <div class=\"documents-menu bg-slate-50\">\n <div class=\"flex flex-row items-center w-full gap-2\">\n <button\n v-if=\"hideSidebar === true || hideSidebar === null\"\n type=\"button\"\n @click=\"hideSidebar = false\"\n class=\"shrink-0 rounded-md p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted\"\n :class=\"hideSidebar === null ? 'lg:hidden' : ''\"\n title=\"Show sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n <document-search\n ref=\"documentSearch\"\n :value=\"searchText\"\n :schema-paths=\"schemaPaths\"\n @search=\"search\"\n >\n </document-search>\n <div>\n <span v-if=\"numDocuments == null\">Loading ...</span>\n <span v-else-if=\"typeof numDocuments === 'number'\">{{documents.length}}/{{numDocuments === 1 ? numDocuments + ' document' : numDocuments + ' documents'}}</span>\n </div>\n <button\n @click=\"stagingSelect\"\n type=\"button\"\n :class=\"{\n 'bg-page0 ring-inset ring-2 ring-gray-300 hover:bg-gray-200 text-content-secondary': selectMultiple,\n 'bg-primary hover:bg-primary-hover text-primary-text': !selectMultiple\n }\"\n class=\"rounded px-2 py-2 text-sm font-semibold shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n {{ selectMultiple ? 'Cancel' : 'Select' }}\n </button>\n <button\n v-show=\"selectMultiple\"\n @click=\"shouldShowUpdateMultipleModal=true;\"\n type=\"button\"\n class=\"rounded bg-green-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600\"\n >\n Update\n </button>\n <button\n @click=\"shouldShowDeleteMultipleModal=true;\"\n type=\"button\"\n v-show=\"selectMultiple\"\n class=\"rounded bg-red-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500\"\n >\n Delete\n </button>\n <div class=\"relative\" v-show=\"!selectMultiple\" ref=\"actionsMenuContainer\" @keyup.esc.prevent=\"closeActionsMenu\">\n <button\n @click=\"toggleActionsMenu\"\n type=\"button\"\n aria-label=\"More actions\"\n class=\"rounded bg-surface px-2 py-2 text-sm font-semibold text-content-secondary shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-page focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z\" />\n </svg>\n </button>\n <div\n v-if=\"showActionsMenu\"\n class=\"absolute right-0 mt-2 w-48 origin-top-right rounded-md bg-surface shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-50\"\n >\n <div class=\"py-1\">\n <button\n @click=\"shouldShowExportModal = true; showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Export\n </button>\n <button\n @click=\"shouldShowCreateModal = true; showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Create\n </button>\n <button\n @click=\"openIndexModal\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Indexes\n </button>\n <button\n @click=\"openCollectionInfo\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Collection Info\n </button>\n <button\n @click=\"findOldestDocument\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Find oldest document\n </button>\n <button\n @click=\"toggleRowNumbers()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n {{ showRowNumbers ? 'Hide row numbers' : 'Show row numbers' }}\n </button>\n <button\n @click=\"resetFilter()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Reset Filter\n </button>\n <button\n @click=\"toggleProjectionMenu(); showActionsMenu = false\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm hover:bg-muted\"\n :class=\"isProjectionMenuSelected ? 'text-primary font-semibold' : 'text-content-secondary'\"\n >\n {{ isProjectionMenuSelected ? 'Projection (On)' : 'Projection' }}\n </button>\n <button\n v-if=\"isProjectionMenuSelected\"\n @click=\"clearProjection()\"\n type=\"button\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Reset Projection\n </button>\n <async-button\n v-if=\"isProjectionMenuSelected\"\n type=\"button\"\n @click=\"applyDefaultProjectionColumns()\"\n class=\"block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted\"\n >\n Default Projection\n </async-button>\n </div>\n </div>\n </div>\n <span class=\"isolate inline-flex rounded-md shadow-sm\">\n <button\n @click=\"setOutputType('table')\"\n type=\"button\"\n class=\"relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10\"\n :class=\"outputType === 'table' ? 'bg-gray-200' : 'bg-surface'\">\n <img class=\"h-5 w-5\" src=\"images/table.svg\">\n </button>\n <button\n @click=\"setOutputType('json')\"\n type=\"button\"\n class=\"relative -ml-px inline-flex items-center px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10\"\n :class=\"outputType === 'json' ? 'bg-gray-200' : 'bg-surface'\">\n <img class=\"h-5 w-5\" src=\"images/json.svg\">\n </button>\n <button\n @click=\"setOutputType('map')\"\n :disabled=\"geoJsonFields.length === 0\"\n type=\"button\"\n :title=\"geoJsonFields.length > 0 ? 'Map view' : 'No GeoJSON fields detected'\"\n class=\"relative -ml-px inline-flex items-center rounded-none rounded-r-md px-2 py-2 ring-1 ring-inset ring-gray-300 focus:z-10\"\n :class=\"[\n geoJsonFields.length === 0 ? 'text-gray-300 cursor-not-allowed bg-muted' : 'text-gray-400 hover:bg-page',\n outputType === 'map' ? 'bg-gray-200' : (geoJsonFields.length > 0 ? 'bg-surface' : '')\n ]\">\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 6.75V15m6-6v8.25m.503 3.498 4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 0 0-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0Z\" />\n </svg>\n </button>\n </span>\n </div>\n <div v-if=\"isProjectionMenuSelected && (outputType === 'table' || outputType === 'json')\" class=\"flex items-center gap-2 w-full mt-2 flex-shrink-0\">\n <input\n ref=\"projectionInput\"\n v-model=\"projectionText\"\n type=\"text\"\n placeholder=\"Projection: name email, or -password\"\n class=\"flex-1 min-w-0 rounded border border-edge bg-surface px-2 py-1.5 text-sm font-mono placeholder:text-content-tertiary focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary\"\n @focus=\"initProjection($event)\"\n @keydown.enter=\"applyProjectionFromInput()\"\n />\n </div>\n </div>\n <!-- In JSON view, this container is the scrollable element used for infinite scroll. -->\n <div class=\"documents-container relative\" ref=\"documentsContainerScroll\" @scroll=\"checkIfScrolledToBottom\">\n <div v-if=\"error\">\n <div class=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 relative m-4 rounded-md\" role=\"alert\">\n <span class=\"block font-bold\">Error</span>\n <span class=\"block\">{{ error }}</span>\n <span class=\"block mt-2\">\n Need help?\n <a\n href=\"https://discord.gg/P3YCfKYxpy\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"underline font-medium text-red-800 hover:text-red-900\"\n >Ask in Discord</a>\n or\n <a\n href=\"https://github.com/mongoosejs/studio/issues\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"underline font-medium text-red-800 hover:text-red-900\"\n >\n open a GitHub issue.\n </a>\n </span>\n </div>\n </div>\n <div v-else-if=\"outputType === 'table'\" class=\"flex-1 min-h-0 flex flex-col overflow-hidden\">\n <div\n ref=\"documentsScrollContainer\"\n class=\"overflow-x-auto overflow-y-auto flex-1 min-h-0 border border-edge rounded-lg bg-surface\"\n @scroll=\"checkIfScrolledToBottom\"\n >\n <table class=\"min-w-full border-collapse text-sm\">\n <thead class=\"sticky top-0 z-10 bg-slate-100 dark:bg-shark-800 border-b border-edge\">\n <tr>\n <th v-if=\"showRowNumbers\" class=\"px-3 py-2.5 text-left font-medium text-content border-r border-edge whitespace-nowrap align-middle w-0\">\n #\n </th>\n <th\n v-for=\"path in tableDisplayPaths\"\n :key=\"path.path\"\n class=\"px-3 py-2.5 text-left font-medium text-content border-r border-edge last:border-r-0 whitespace-nowrap align-middle\"\n >\n <div class=\"flex items-center gap-2\">\n <span\n @click=\"addPathFilter(path.path)\"\n class=\"cursor-pointer hover:text-primary truncate min-w-0\"\n :title=\"path.path\"\n >\n {{ path.path }}\n </span>\n <span class=\"text-xs text-content-tertiary shrink-0\">({{ path.instance || 'unknown' }})</span>\n <span class=\"inline-flex shrink-0 gap-0.5 items-center\">\n <button\n type=\"button\"\n @click.stop=\"sortDocs(1, path.path)\"\n class=\"p-0.5 rounded text-content-tertiary hover:text-content hover:bg-muted\"\n :class=\"{ 'text-primary font-semibold': sortBy[path.path] === 1 }\"\n :title=\"sortBy[path.path] === 1 ? 'Clear sort' : 'Sort ascending'\"\n >\n ↑\n </button>\n <button\n type=\"button\"\n @click.stop=\"sortDocs(-1, path.path)\"\n class=\"p-0.5 rounded text-content-tertiary hover:text-content hover:bg-muted\"\n :class=\"{ 'text-primary font-semibold': sortBy[path.path] === -1 }\"\n :title=\"sortBy[path.path] === -1 ? 'Clear sort' : 'Sort descending'\"\n >\n ↓\n </button>\n <button\n v-if=\"filteredPaths.length > 0\"\n type=\"button\"\n @click.stop=\"removeField(path)\"\n class=\"p-1.5 rounded-md border border-transparent text-content-tertiary hover:text-valencia-600 hover:bg-valencia-50 hover:border-valencia-200 focus:outline-none focus:ring-2 focus:ring-valencia-500/30\"\n title=\"Remove column\"\n aria-label=\"Remove column\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </span>\n </div>\n </th>\n <th v-if=\"filteredPaths.length > 0\" class=\"px-2 py-2.5 border-r border-edge last:border-r-0 align-middle w-0 bg-slate-50 dark:bg-shark-800/80\">\n <div class=\"relative\" ref=\"addFieldContainer\">\n <button\n type=\"button\"\n @click=\"toggleAddFieldDropdown()\"\n class=\"flex items-center justify-center w-8 h-8 rounded border border-dashed border-edge text-content-tertiary hover:border-primary hover:text-primary hover:bg-primary-subtle/30\"\n title=\"Add column\"\n aria-label=\"Add column\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" class=\"w-5 h-5\"> <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" /> </svg>\n </button>\n <div\n v-if=\"showAddFieldDropdown\"\n class=\"absolute right-0 top-full mt-1 z-[100] min-w-[180px] max-w-[280px] rounded-md border border-edge bg-surface shadow-lg py-1 max-h-48 overflow-y-auto\"\n >\n <input\n v-if=\"availablePathsToAdd.length > 5\"\n ref=\"addFieldFilterInput\"\n v-model=\"addFieldFilterText\"\n type=\"text\"\n placeholder=\"Filter fields...\"\n class=\"mx-2 mb-1 w-[calc(100%-1rem)] rounded border border-edge px-2 py-1 text-sm\"\n @click.stop\n />\n <button\n v-for=\"p in filteredPathsToAdd\"\n :key=\"p.path\"\n type=\"button\"\n class=\"w-full px-3 py-1.5 text-left text-sm hover:bg-muted\"\n @click.stop=\"addField(p)\"\n >\n {{ p.path }}\n </button>\n <p v-if=\"filteredPathsToAdd.length === 0\" class=\"px-3 py-2 text-sm text-content-tertiary\">\n {{ addFieldFilterText.trim() ? 'No matching fields' : 'All fields added' }}\n </p>\n </div>\n </div>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-surface\">\n <tr\n v-for=\"(document, docIndex) in documents\"\n :key=\"document._id\"\n @click=\"handleDocumentClick(document, $event)\"\n class=\"border-b border-edge cursor-pointer transition-colors hover:bg-muted/60\"\n :class=\"{ 'bg-primary-subtle/50 hover:bg-primary-subtle/70': selectedDocuments.some(x => x._id.toString() === document._id.toString()) }\"\n >\n <td v-if=\"showRowNumbers\" class=\"px-3 py-2 border-r border-edge align-top text-content-tertiary whitespace-nowrap\">\n {{ docIndex + 1 }}\n </td>\n <td\n v-for=\"schemaPath in tableDisplayPaths\"\n :key=\"schemaPath.path\"\n class=\"px-3 py-2 border-r border-edge last:border-r-0 align-top max-w-[280px]\"\n >\n <div class=\"table-cell-content flex items-center gap-1.5 min-w-0 group\">\n <span class=\"min-w-0 overflow-hidden text-ellipsis flex-1\">\n <component\n :is=\"getComponentForPath(schemaPath)\"\n :value=\"getValueForPath(document, schemaPath.path)\"\n :allude=\"getReferenceModel(schemaPath)\"\n />\n </span>\n <button\n type=\"button\"\n class=\"table-cell-copy shrink-0 p-1 rounded text-content-tertiary hover:text-content hover:bg-muted focus:outline-none focus:ring-1 focus:ring-edge\"\n aria-label=\"Copy cell value\"\n @click.stop=\"copyCellValue(getValueForPath(document, schemaPath.path))\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-5 h-5\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 5H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-1M8 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M8 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m0 0h2a2 2 0 0 1 2 2v3m2 4H10m0 0l3-3m-3 3l3 3\" />\n </svg>\n </button>\n </div>\n </td>\n <td v-if=\"filteredPaths.length > 0\" class=\"w-0 px-0 py-0 border-r border-edge last:border-r-0 bg-slate-50/50 dark:bg-shark-800/30\"></td>\n </tr>\n </tbody>\n </table>\n </div>\n <div v-if=\"outputType === 'table' && (loadingMore || (status === 'loading' && documents.length > 0))\" class=\"flex items-center justify-center gap-2 py-3 text-sm text-content-tertiary border-t border-edge bg-surface\">\n <img src=\"images/loader.gif\" alt=\"\" class=\"h-5 w-5\">\n <span>Loading documents…</span>\n </div>\n <p v-if=\"outputType === 'table' && documents.length === 0 && status === 'loaded'\" class=\"mt-2 text-sm text-content-tertiary px-1\">\n No documents to show. Use Projection in the menu to choose columns.\n </p>\n </div>\n <div v-else-if=\"outputType === 'json'\" class=\"flex flex-col space-y-2 p-1 mt-1\">\n <div\n v-for=\"document in documents\"\n :key=\"document._id\"\n @click=\"handleDocumentContainerClick(document, $event)\"\n :class=\"[\n 'group relative transition-colors rounded-md border border-slate-100',\n selectedDocuments.some(x => x._id.toString() === document._id.toString()) ? 'bg-blue-200' : 'hover:shadow-sm hover:border-slate-300 bg-surface'\n ]\"\n >\n <router-link\n class=\"absolute top-2 right-2 z-10 inline-flex items-center rounded bg-primary px-2 py-1 text-xs font-semibold text-primary-text shadow-sm transition-opacity duration-150 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n :to=\"{ path: '/model/' + currentModel + '/document/' + document._id, query: $route.query }\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n @click.stop\n >\n Open\n </router-link>\n <list-json :value=\"filterDocument(document)\" :references=\"referenceMap\">\n </list-json>\n </div>\n <div v-if=\"outputType === 'json' && (loadingMore || (status === 'loading' && documents.length > 0))\" class=\"flex items-center justify-center gap-2 py-3 text-sm text-content-tertiary\">\n <img src=\"images/loader.gif\" alt=\"\" class=\"h-5 w-5\">\n <span>Loading documents…</span>\n </div>\n </div>\n <div v-else-if=\"outputType === 'map'\" class=\"flex flex-col h-full\">\n <div class=\"p-2 bg-surface border-b flex items-center gap-2\">\n <label class=\"text-sm font-medium text-content-secondary\">GeoJSON Field:</label>\n <select\n :value=\"selectedGeoField\"\n @change=\"setSelectedGeoField($event.target.value)\"\n class=\"rounded-md border border-edge-strong py-1 px-2 text-sm focus:border-primary focus:ring-primary\"\n >\n <option v-for=\"field in geoJsonFields\" :key=\"field.path\" :value=\"field.path\">\n {{ field.label }}\n </option>\n </select>\n <async-button\n @click=\"loadMoreDocuments\"\n :disabled=\"loadedAllDocs\"\n type=\"button\"\n class=\"rounded px-2 py-1 text-xs font-semibold text-primary-text shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n :class=\"loadedAllDocs ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary hover:bg-primary-hover'\"\n >\n Load more\n </async-button>\n </div>\n <div class=\"flex-1 min-h-[400px]\" ref=\"modelsMap\"></div>\n </div>\n <div v-if=\"status === 'loading' && !loadingMore && documents.length === 0\" class=\"loader loader-overlay\" aria-busy=\"true\">\n <img src=\"images/loader.gif\" alt=\"Loading\">\n </div>\n </div>\n </div>\n <modal v-if=\"shouldShowExportModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowExportModal = false\">×</div>\n <export-query-results\n :schemaPaths=\"schemaPaths\"\n :search-text=\"searchText\"\n :currentModel=\"currentModel\"\n @done=\"shouldShowExportModal = false\">\n </export-query-results>\n </template>\n </modal>\n <modal v-if=\"shouldShowIndexModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowIndexModal = false\">×</div>\n <div class=\"text-xl font-bold mb-2\">Indexes</div>\n <div v-for=\"index in mongoDBIndexes\" class=\"w-full flex items-center\">\n <div class=\"grow shrink text-left flex justify-between items-center\" v-if=\"index.name != '_id_'\">\n <div>\n <div class=\"font-bold flex items-center gap-2\">\n <div>{{ index.name }}</div>\n <div v-if=\"isTTLIndex(index)\" class=\"rounded-full bg-primary-subtle px-2 py-0.5 text-xs font-semibold text-primary\">\n TTL: {{ formatTTL(index.expireAfterSeconds) }}\n </div>\n </div>\n <div class=\"text-sm font-mono\">{{ JSON.stringify(index.key) }}</div>\n </div>\n <div>\n <async-button\n type=\"button\"\n @click=\"dropIndex(index.name)\"\n class=\"rounded-md bg-valencia-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-valencia-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600 disabled:bg-gray-400 disabled:cursor-not-allowed\">\n Drop\n </async-button>\n </div>\n </div>\n </div>\n </template>\n </modal>\n <modal v-if=\"shouldShowCollectionInfoModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowCollectionInfoModal = false\">×</div>\n <div class=\"text-xl font-bold mb-2\">Collection Info</div>\n <div v-if=\"!collectionInfo\" class=\"text-gray-600\">Loading collection details...</div>\n <div v-else class=\"space-y-3\">\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Documents</div>\n <div class=\"text-content\">{{ formatNumber(collectionInfo.documentCount) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Indexes</div>\n <div class=\"text-content\">{{ formatNumber(collectionInfo.indexCount) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Total Index Size</div>\n <div class=\"text-content\">{{ formatCollectionSize(collectionInfo.totalIndexSize) }}</div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Total Storage Size</div>\n <div class=\"text-content\">{{ formatCollectionSize(collectionInfo.size) }}</div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Collation</div>\n <div class=\"text-content\">{{ collectionInfo.hasCollation ? 'Yes' : 'No' }}</div>\n </div>\n <div v-if=\"collectionInfo.hasCollation\" class=\"rounded bg-muted p-3 text-sm text-gray-800 overflow-x-auto\">\n <pre class=\"whitespace-pre-wrap\">{{ JSON.stringify(collectionInfo.collation, null, 2) }}</pre>\n </div>\n </div>\n <div class=\"flex justify-between gap-4\">\n <div class=\"font-semibold text-content-secondary\">Capped</div>\n <div class=\"text-content\">{{ collectionInfo.capped ? 'Yes' : 'No' }}</div>\n </div>\n </div>\n </template>\n </modal>\n <modal v-if=\"shouldShowCreateModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowCreateModal = false;\">×</div>\n <create-document :currentModel=\"currentModel\" :paths=\"schemaPaths\" @close=\"closeCreationModal\"></create-document>\n </template>\n </modal>\n <modal v-if=\"shouldShowUpdateMultipleModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowUpdateMultipleModal = false;\">×</div>\n <update-document :currentModel=\"currentModel\" :document=\"selectedDocuments\" :multiple=\"true\" @update=\"updateDocuments\" @close=\"shouldShowUpdateMultipleModal=false;\"></update-document>\n </template>\n </modal>\n <modal v-if=\"shouldShowDeleteMultipleModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowDeleteMultipleModal = false;\">×</div>\n <h2>Are you sure you want to delete {{selectedDocuments.length}} documents?</h2>\n <div>\n <list-json :value=\"selectedDocuments\"></list-json>\n </div>\n <div class=\"flex gap-4\">\n <async-button @click=\"deleteDocuments\" class=\"rounded bg-red-500 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600\">\n Confirm\n </async-button>\n <button @click=\"shouldShowDeleteMultipleModal = false;\" class=\"rounded bg-gray-400 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-page0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500\">\n Cancel\n </button>\n </div>\n </template>\n </modal>\n <model-switcher\n :show=\"showModelSwitcher\"\n :models=\"models\"\n :recently-viewed-models=\"recentlyViewedModels\"\n :model-document-counts=\"modelDocumentCounts\"\n @close=\"showModelSwitcher = false\"\n @select=\"selectSwitcherModel\"\n ></model-switcher>\n</div>\n";
|
|
50738
51426
|
|
|
50739
51427
|
/***/ },
|
|
50740
51428
|
|
|
@@ -50756,7 +51444,18 @@ module.exports = ".active {\n text-decoration: underline;\n}\n\n.navbar .nav-le
|
|
|
50756
51444
|
(module) {
|
|
50757
51445
|
|
|
50758
51446
|
"use strict";
|
|
50759
|
-
module.exports = "<div class=\"navbar w-full bg-page border-b border-edge !h-[55px] hidden md:grid grid-cols-[1fr_auto_1fr] items-stretch px-4\">\n <!-- Left: Logo + Brand -->\n <div class=\"flex items-center gap-2 self-center\">\n <router-link class=\"flex items-center gap-2\" :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-10 text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n <span class=\"text-base font-semibold text-content whitespace-nowrap\">Mongoose Studio</span>\n </router-link>\n </div>\n <!-- Center: Nav Links -->\n <nav class=\"flex items-stretch gap-6\">\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"documentView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Documents</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\" aria-disabled=\"true\">\n Documents\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"dashboardView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Dashboards</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\">\n Dashboards\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"chatView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Chat</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\">\n Chat\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a\n :href=\"hasTaskVisualizer\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"taskView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">\n Tasks\n </a>\n <a\n href=\"https://studio.mongoosejs.io/docs\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-content-tertiary hover:text-content\"\n >\n Docs\n </a>\n </nav>\n <!-- Right: Env Badge + User -->\n <div class=\"flex items-center justify-end gap-3 self-center\">\n <div\n v-if=\"!!state.nodeEnv\"\n title=\"NODE_ENV\"\n class=\"inline-flex items-center rounded px-2 py-1 text-xs text-content-tertiary bg-surface border border-edge gap-2\"\n >\n <span\n :class=\"warnEnv ? 'bg-red-400' : 'bg-yellow-400'\"\n class=\"inline-block rounded-full\"\n style=\"width: 0.5em; height: 0.5em;\"\n ></span>\n <span>{{state.nodeEnv}}</span>\n </div>\n <button\n v-if=\"!user || !hasAPIKey\"\n type=\"button\"\n @click=\"toggleDarkMode\"\n :title=\"darkMode ? 'Switch to light mode' : 'Switch to dark mode'\"\n class=\"inline-flex items-center justify-center rounded-md p-2 text-content-tertiary hover:text-content-secondary hover:bg-muted\"\n aria-label=\"Toggle dark mode\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/>\n </svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/>\n </svg>\n </button>\n <div class=\"flex items-center\" v-if=\"!user && hasAPIKey\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-primary px-2 py-2 text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"flex items-center relative\" v-clickOutside=\"hideFlyout\">\n <button type=\"button\" @click=\"showFlyout = !showFlyout\" class=\"relative flex rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-gray-300\" id=\"user-menu-button\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"absolute -inset-1.5\"></span>\n <span class=\"sr-only\">Open user menu</span>\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n </button>\n\n <div\n v-if=\"showFlyout\"\n class=\"absolute right-0 top-[90%] w-48 origin-top-right rounded-md bg-surface py-1 shadow-lg ring-1 ring-black/5 focus:outline-none\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-labelledby=\"user-menu-button\"\n style=\"z-index: 10000\"\n tabindex=\"-1\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode(); showFlyout = false\"\n class=\"w-full cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle text-left flex items-center gap-2\"\n role=\"menuitem\"\n tabindex=\"-1\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n {{ darkMode ? 'Light mode' : 'Dark mode' }}\n </button>\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" @click=\"showFlyout = false\" class=\"cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Team</router-link>\n <span v-else class=\"block px-4 py-2 text-sm text-gray-300 cursor-not-allowed\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">\n Team\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <span @click=\"logout\" class=\"cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Sign out</span>\n </div>\n </div>\n </div>\n</div>\n<!-- Mobile navbar -->\n<div class=\"navbar w-full bg-page flex justify-between border-b border-edge !h-[55px] md:hidden\">\n <div class=\"flex items-center gap-2 pl-4\">\n <router-link class=\"flex items-center gap-2\" :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-8 text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n <span class=\"text-base font-semibold text-content\">Mongoose Studio</span>\n </router-link>\n </div>\n <div class=\"flex items-center\">\n <!-- Mobile menu toggle, controls the 'mobileMenuOpen' state. -->\n <button type=\"button\" id=\"open-mobile-menu\" class=\"-ml-2 rounded-md p-2 pr-4 text-gray-400\">\n <span class=\"sr-only\">Open menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5\" />\n </svg>\n </button>\n </div>\n\n <!-- Mobile menu mask -->\n <div id=\"mobile-menu-mask\" class=\"fixed inset-0 bg-black bg-opacity-40 z-40 hidden\"></div>\n <!-- Mobile menu drawer -->\n <div id=\"mobile-menu\" style=\"z-index: 10000\" class=\"fixed inset-0 bg-page shadow-lg transform translate-x-full transition-transform duration-200 ease-in-out flex flex-col\">\n <div class=\"flex items-center justify-between px-4 !h-[55px] border-b border-edge\">\n <router-link :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-[32px] text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n </router-link>\n <button type=\"button\" id=\"close-mobile-menu\" class=\"text-gray-400 p-2 rounded-md\">\n <span class=\"sr-only\">Close menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <nav class=\"flex-1 px-4 py-4 space-y-2\">\n <div class=\"flex items-center gap-2 px-3 py-2\" v-if=\"!user || !hasAPIKey\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode\"\n class=\"inline-flex items-center gap-2 rounded-md px-3 py-2 text-base font-medium text-content-secondary hover:bg-muted\"\n aria-label=\"Toggle dark mode\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n <span>{{ darkMode ? 'Light mode' : 'Dark mode' }}</span>\n </button>\n </div>\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"documentView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Documents</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Documents\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"dashboardView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Dashboards</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Dashboards\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"chatView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Chat</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Chat\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <div v-if=\"!user && hasAPIKey\" class=\"mt-4\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"w-full rounded bg-muted text-content px-3 py-2 text-base font-semibold shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"mt-4\">\n <div class=\"flex items-center gap-3 px-3 py-2 bg-page rounded-md\">\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n <span class=\"text-content font-medium\">{{ user.name }}</span>\n </div>\n <div class=\"mt-2 space-y-1\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode\"\n class=\"w-full inline-flex items-center gap-2 px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle text-left\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n {{ darkMode ? 'Light mode' : 'Dark mode' }}\n </button>\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" class=\"block px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle\">Team</router-link>\n <span v-else class=\"block px-3 py-2 rounded-md text-base text-gray-300 cursor-not-allowed\">\n Team\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <span @click=\"logout\" class=\"block px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle cursor-pointer\">Sign out</span>\n </div>\n </div>\n </nav>\n </div>\n</div>\n";
|
|
51447
|
+
module.exports = "<div class=\"navbar w-full bg-page border-b border-edge !h-[55px] hidden md:grid grid-cols-[1fr_auto_1fr] items-stretch px-4\">\n <!-- Left: Logo + Brand -->\n <div class=\"flex items-center gap-2 self-center\">\n <router-link class=\"flex items-center gap-2\" :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-10 text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n <span class=\"text-base font-semibold text-content whitespace-nowrap\">Mongoose Studio</span>\n </router-link>\n </div>\n <!-- Center: Nav Links -->\n <nav class=\"flex items-stretch gap-6\">\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"documentView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Documents</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\" aria-disabled=\"true\">\n Documents\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"dashboardView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Dashboards</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\">\n Dashboards\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"chatView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">Chat</a>\n <span v-else class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-gray-300 cursor-not-allowed\">\n Chat\n <svg class=\"h-4 w-4 ml-1\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a\n v-if=\"hasTaskVisualizer\"\n href=\"#/tasks\"\n class=\"inline-flex items-center px-1 border-b-2 text-sm font-medium\"\n :class=\"taskView ? 'text-content border-primary' : 'border-transparent text-content-tertiary hover:text-content'\">\n Tasks\n </a>\n <a\n href=\"https://studio.mongoosejs.io/docs\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"inline-flex items-center px-1 border-b-2 border-transparent text-sm font-medium text-content-tertiary hover:text-content\"\n >\n Docs\n </a>\n </nav>\n <!-- Right: Env Badge + User -->\n <div class=\"flex items-center justify-end gap-3 self-center\">\n <div\n v-if=\"!!state.nodeEnv\"\n title=\"NODE_ENV\"\n class=\"inline-flex items-center rounded px-2 py-1 text-xs text-content-tertiary bg-surface border border-edge gap-2\"\n >\n <span\n :class=\"warnEnv ? 'bg-red-400' : 'bg-yellow-400'\"\n class=\"inline-block rounded-full\"\n style=\"width: 0.5em; height: 0.5em;\"\n ></span>\n <span>{{state.nodeEnv}}</span>\n </div>\n <button\n v-if=\"!user || !hasAPIKey\"\n type=\"button\"\n @click=\"toggleDarkMode\"\n :title=\"darkMode ? 'Switch to light mode' : 'Switch to dark mode'\"\n class=\"inline-flex items-center justify-center rounded-md p-2 text-content-tertiary hover:text-content-secondary hover:bg-muted\"\n aria-label=\"Toggle dark mode\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/>\n </svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/>\n </svg>\n </button>\n <div class=\"flex items-center\" v-if=\"!user && hasAPIKey\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-primary px-2 py-2 text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"flex items-center relative\" v-clickOutside=\"hideFlyout\">\n <button type=\"button\" @click=\"showFlyout = !showFlyout\" class=\"relative flex rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-gray-300\" id=\"user-menu-button\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"absolute -inset-1.5\"></span>\n <span class=\"sr-only\">Open user menu</span>\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n </button>\n\n <div\n v-if=\"showFlyout\"\n class=\"absolute right-0 top-[90%] w-48 origin-top-right rounded-md bg-surface py-1 shadow-lg ring-1 ring-black/5 focus:outline-none\"\n role=\"menu\"\n aria-orientation=\"vertical\"\n aria-labelledby=\"user-menu-button\"\n style=\"z-index: 10000\"\n tabindex=\"-1\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode(); showFlyout = false\"\n class=\"w-full cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle text-left flex items-center gap-2\"\n role=\"menuitem\"\n tabindex=\"-1\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n {{ darkMode ? 'Light mode' : 'Dark mode' }}\n </button>\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" @click=\"showFlyout = false\" class=\"cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Team</router-link>\n <span v-else class=\"block px-4 py-2 text-sm text-gray-300 cursor-not-allowed\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">\n Team\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <span @click=\"logout\" class=\"cursor-pointer block px-4 py-2 text-sm text-content-secondary hover:bg-primary-subtle\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Sign out</span>\n </div>\n </div>\n </div>\n</div>\n<!-- Mobile navbar -->\n<div class=\"navbar w-full bg-page flex justify-between border-b border-edge !h-[55px] md:hidden\">\n <div class=\"flex items-center gap-2 pl-4\">\n <router-link class=\"flex items-center gap-2\" :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-8 text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n <span class=\"text-base font-semibold text-content\">Mongoose Studio</span>\n </router-link>\n </div>\n <div class=\"flex items-center\">\n <!-- Mobile menu toggle, controls the 'mobileMenuOpen' state. -->\n <button type=\"button\" id=\"open-mobile-menu\" class=\"-ml-2 rounded-md p-2 pr-4 text-gray-400\">\n <span class=\"sr-only\">Open menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5\" />\n </svg>\n </button>\n </div>\n\n <!-- Mobile menu mask -->\n <div id=\"mobile-menu-mask\" class=\"fixed inset-0 bg-black bg-opacity-40 z-40 hidden\"></div>\n <!-- Mobile menu drawer -->\n <div id=\"mobile-menu\" style=\"z-index: 10000\" class=\"fixed inset-0 bg-page shadow-lg transform translate-x-full transition-transform duration-200 ease-in-out flex flex-col\">\n <div class=\"flex items-center justify-between px-4 !h-[55px] border-b border-edge\">\n <router-link :to=\"{ name: defaultRoute }\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-[32px] text-primary\" viewBox=\"0 0 250 250\" fill=\"currentColor\" aria-label=\"Mongoose Studio Logo\">\n <path d=\"M 241.66,125.01 C 237.81,112.98 227.41,111.95 216.76,110.36 C 215.12,95.83 210.99,83.09 202.29,70.33 C 202.99,68.37 201.92,66.65 200.74,65.11 C 183.14,41.46 157.52,27 124.66,27 C 92.62,27 66.09,40.77 48.28,63.38 C 46.21,65.85 46.26,67.71 47.12,69.36 C 37.81,81.15 33.21,93.78 30.99,109.86 C 20.19,110.58 11.71,115.92 9.04,124.94 C 3.28,145.66 5.62,157.95 10.01,169.16 C 16.14,184.65 29.12,186.31 36.04,185.81 C 42.48,185.68 44.94,184.31 44.72,182.11 C 44.26,177.79 41.01,165.31 41.01,149.12 C 41.01,138.22 43.19,127.74 46.21,117.7 C 47.51,113.33 44.66,112.05 39.16,110.28 C 41.01,96.88 45.88,84.85 52.61,73.79 C 55.17,75.56 58.07,74.88 59.61,72.71 C 75.86,54.31 97.89,45.16 124.61,45.16 C 149.71,45.16 171.91,55.91 189.29,73.47 C 191.95,76.59 193.91,76.67 197.6,74.42 C 204.93,86.26 208.28,98.24 208.98,110.39 C 203.84,111.81 201.28,113.19 202.92,118.61 C 206.51,128.99 207.92,137.93 207.92,148.73 C 207.92,162.11 204.8,174.71 202.84,182.71 C 201.92,186.23 204.31,186.91 210.79,186.99 H 213.91 C 225.87,186.61 235.39,180.64 239.49,169.05 C 244.83,155.26 245.08,138.01 241.66,125.01 Z\"/>\n <path d=\"M 124.71,70.81 C 79.63,70.81 47.49,107.12 47.49,148.72 C 47.49,169.16 56.41,188.19 73.71,200.61 L 73.96,200.77 C 77.43,177.81 84.16,162.21 95.29,145.42 C 92.04,137.09 91.71,130.87 92.62,120.83 C 93.81,111.23 96.08,107.12 102.19,107.68 C 110.04,108.87 117.98,116.18 126.22,124.96 C 139.89,124.05 157.81,131.25 178.33,139.09 C 183.11,140.86 183.72,142.63 182.97,148.33 C 179.45,160.93 170.86,166.63 158.11,174.05 C 143.09,183.07 141.13,199.42 153.88,220.09 L 153.96,221.01 L 154.71,221.17 C 181.31,208.43 201.34,181.01 201.34,148.72 C 201.34,108.15 169.29,70.81 124.71,70.81 Z\"/>\n </svg>\n </router-link>\n <button type=\"button\" id=\"close-mobile-menu\" class=\"text-gray-400 p-2 rounded-md\">\n <span class=\"sr-only\">Close menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <nav class=\"flex-1 px-4 py-4 space-y-2\">\n <div class=\"flex items-center gap-2 px-3 py-2\" v-if=\"!user || !hasAPIKey\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode\"\n class=\"inline-flex items-center gap-2 rounded-md px-3 py-2 text-base font-medium text-content-secondary hover:bg-muted\"\n aria-label=\"Toggle dark mode\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n <span>{{ darkMode ? 'Light mode' : 'Dark mode' }}</span>\n </button>\n </div>\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"documentView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Documents</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Documents\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"dashboardView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Dashboards</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Dashboards\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"chatView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Chat</a>\n <span v-else class=\"block px-3 py-2 rounded-md text-base font-medium text-gray-300 cursor-not-allowed\">\n Chat\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <a v-if=\"hasTaskVisualizer\"\n href=\"#/tasks\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"taskView ? 'text-content bg-primary-subtle' : 'text-content-secondary hover:bg-muted'\">Tasks</a>\n <div v-if=\"!user && hasAPIKey\" class=\"mt-4\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"w-full rounded bg-muted text-content px-3 py-2 text-base font-semibold shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"mt-4\">\n <div class=\"flex items-center gap-3 px-3 py-2 bg-page rounded-md\">\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n <span class=\"text-content font-medium\">{{ user.name }}</span>\n </div>\n <div class=\"mt-2 space-y-1\">\n <button\n type=\"button\"\n @click=\"toggleDarkMode\"\n class=\"w-full inline-flex items-center gap-2 px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle text-left\">\n <svg v-if=\"darkMode\" xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z\"/></svg>\n {{ darkMode ? 'Light mode' : 'Dark mode' }}\n </button>\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" class=\"block px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle\">Team</router-link>\n <span v-else class=\"block px-3 py-2 rounded-md text-base text-gray-300 cursor-not-allowed\">\n Team\n <svg class=\"h-4 w-4 ml-1 inline\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 2a4 4 0 00-4 4v2H5a2 2 0 00-2 2v6a2 2 0 002 2h10a2 2 0 002-2v-6a2 2 0 00-2-2h-1V6a4 4 0 00-4-4zm-3 6V6a3 3 0 116 0v2H7z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <span @click=\"logout\" class=\"block px-3 py-2 rounded-md text-base text-content-secondary hover:bg-primary-subtle cursor-pointer\">Sign out</span>\n </div>\n </div>\n </nav>\n </div>\n</div>\n";
|
|
51448
|
+
|
|
51449
|
+
/***/ },
|
|
51450
|
+
|
|
51451
|
+
/***/ "./frontend/src/pro-upgrade-modal/pro-upgrade-modal.html"
|
|
51452
|
+
/*!***************************************************************!*\
|
|
51453
|
+
!*** ./frontend/src/pro-upgrade-modal/pro-upgrade-modal.html ***!
|
|
51454
|
+
\***************************************************************/
|
|
51455
|
+
(module) {
|
|
51456
|
+
|
|
51457
|
+
"use strict";
|
|
51458
|
+
module.exports = "<modal v-if=\"show\" containerClass=\"!max-w-md\">\n <template v-slot:body>\n <div @keydown.esc=\"$emit('close')\" tabindex=\"0\" ref=\"overlay\">\n <div class=\"flex items-center justify-between mb-4\">\n <h3 class=\"text-lg font-semibold text-gray-900\">Pro Feature</h3>\n <button\n type=\"button\"\n @click=\"$emit('close')\"\n class=\"text-gray-400 hover:text-gray-600 cursor-pointer\"\n aria-label=\"Close\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18 18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <p class=\"text-gray-600 mb-6\">\n {{ featureDescription }} Upgrade to a Pro workspace to unlock this feature.\n </p>\n <div class=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n @click=\"$emit('close')\"\n class=\"px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 cursor-pointer\"\n >\n Cancel\n </button>\n <a\n href=\"https://studio.mongoosejs.io/pro\"\n target=\"_blank\"\n class=\"px-4 py-2 text-sm font-medium text-white bg-primary rounded-md hover:bg-primary-hover inline-flex items-center\"\n >\n Upgrade to Pro\n </a>\n </div>\n </div>\n </template>\n</modal>\n";
|
|
50760
51459
|
|
|
50761
51460
|
/***/ },
|
|
50762
51461
|
|
|
@@ -50822,7 +51521,7 @@ module.exports = "";
|
|
|
50822
51521
|
(module) {
|
|
50823
51522
|
|
|
50824
51523
|
"use strict";
|
|
50825
|
-
module.exports = "<div class=\"p-4 space-y-6\">\n <div>\n <h1 class=\"text-2xl font-bold text-content-secondary mb-4\">Task Overview</h1>\n <div v-if=\"status == 'init'\">\n <img src=\"images/loader.gif\" />\n </div>\n <!-- Task List -->\n <div class=\"bg-surface p-4 rounded-lg shadow\" v-if=\"status == 'loaded'\">\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Filter by Date:</label>\n <select v-model=\"selectedRange\" @change=\"updateDateRange\" class=\"border-edge-strong rounded-md shadow-sm w-full p-2\">\n <option v-for=\"option in dateFilters\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Filter by Status:</label>\n <select v-model=\"selectedStatus\" @change=\"getTasks\" class=\"border-edge-strong rounded-md shadow-sm w-full p-2\">\n <option v-for=\"option in statusFilters\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Search by Task Name:</label>\n <input \n v-model=\"searchQuery\" \n type=\"text\" \n @input=\"onSearchInput\"\n class=\"border-edge-strong rounded-md shadow-sm w-full p-2\"\n placeholder=\"Enter task name to search...\"\n >\n </div>\n <div class=\"mb-4\">\n <button\n @click=\"resetFilters\"\n class=\"w-full bg-gray-200 text-content-secondary hover:bg-gray-300 font-medium py-2 px-4 rounded-md transition\"\n >\n Reset Filters\n </button>\n </div>\n <div class=\"mb-6\">\n <button\n @click=\"openCreateTaskModal\"\n class=\"w-full bg-primary text-primary-text hover:bg-primary-hover font-medium py-2 px-4 rounded-md transition\"\n >\n Create New Task\n </button>\n </div>\n <!-- Summary Section -->\n <div class=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n <button \n @click=\"setStatusFilter('pending')\"\n :class=\"getStatusColor('pending') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-yellow-200 hover:border-yellow-300'\"\n >\n <div class=\"text-sm\">Scheduled</div>\n <div class=\"text-2xl font-bold\">{{pendingCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('succeeded')\"\n :class=\"getStatusColor('succeeded') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-green-200 hover:border-green-300'\"\n >\n <div class=\"text-sm\">Completed</div>\n <div class=\"text-2xl font-bold\">{{succeededCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('failed')\"\n :class=\"getStatusColor('failed') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-red-200 hover:border-red-300'\"\n >\n <div class=\"text-sm\">Failed</div>\n <div class=\"text-2xl font-bold\">{{failedCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('cancelled')\"\n :class=\"getStatusColor('cancelled') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-edge hover:border-edge-strong'\"\n >\n <div class=\"text-sm\">Cancelled</div>\n <div class=\"text-2xl font-bold\">{{cancelledCount}}</div>\n </button>\n </div>\n \n <!-- Grouped Task List -->\n <div class=\"mt-6\">\n <h2 class=\"text-lg font-semibold text-content-secondary mb-4\">Tasks by Name</h2>\n <ul class=\"divide-y divide-gray-200\">\n <li v-for=\"group in tasksByName\" :key=\"group.name\" class=\"p-4 group hover:border hover:rounded-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200\">\n <div class=\"flex items-center justify-between mb-3 \">\n <div class=\"flex-1 cursor-pointer\" @click=\"openTaskGroupDetails(group)\">\n <div class=\"flex items-center gap-2\">\n <div class=\"font-medium text-lg group-hover:text-primary transition-colors\">{{ group.name }}</div>\n <svg class=\"w-4 h-4 text-gray-400 group-hover:text-primary transition-colors\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"></path>\n </svg>\n </div>\n <div class=\"text-sm text-content-tertiary group-hover:text-content-secondary transition-colors\">Total: {{ group.totalCount }} tasks</div>\n <div class=\"text-xs text-primary opacity-0 group-hover:opacity-100 transition-opacity mt-1\">\n Click to view details\n </div>\n </div>\n <div class=\"text-sm text-content-tertiary\">\n Last run: {{ group.lastRun ? new Date(group.lastRun).toLocaleString() : 'Never' }}\n </div>\n </div>\n \n <!-- Status Counts -->\n <div class=\"grid grid-cols-2 sm:grid-cols-4 gap-2\">\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'pending')\"\n class=\"bg-yellow-50 border border-yellow-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-yellow-300\"\n >\n <div class=\"text-xs text-yellow-600 font-medium\">Pending</div>\n <div class=\"text-lg font-bold text-yellow-700\">{{ group.statusCounts.pending || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'succeeded')\"\n class=\"bg-green-50 border border-green-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-green-300\"\n >\n <div class=\"text-xs text-green-600 font-medium\">Succeeded</div>\n <div class=\"text-lg font-bold text-green-700\">{{ group.statusCounts.succeeded || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'failed')\"\n class=\"bg-red-50 border border-red-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-red-300\"\n >\n <div class=\"text-xs text-red-600 font-medium\">Failed</div>\n <div class=\"text-lg font-bold text-red-700\">{{ group.statusCounts.failed || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'cancelled')\"\n class=\"bg-page border border-edge rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-edge-strong\"\n >\n <div class=\"text-xs text-gray-600 font-medium\">Cancelled</div>\n <div class=\"text-lg font-bold text-content-secondary\">{{ group.statusCounts.cancelled || 0 }}</div>\n </button>\n </div>\n </li>\n </ul>\n </div>\n </div>\n </div>\n\n <!-- Create Task Modal -->\n <modal v-if=\"showCreateTaskModal\" containerClass=\"!h-[90vh] !w-[90vw]\">\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"closeCreateTaskModal\" role=\"button\" aria-label=\"Close modal\">×</div>\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold text-content-secondary mb-4\">Create New Task</h3>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Task Name:</label>\n <input \n v-model=\"newTask.name\" \n type=\"text\" \n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Enter task name\"\n >\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Scheduled Time:</label>\n <input \n v-model=\"newTask.scheduledAt\" \n type=\"datetime-local\" \n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Parameters (JSON):</label>\n <ace-editor\n v-model=\"newTask.parameters\"\n mode=\"json\"\n :line-numbers=\"true\"\n class=\"min-h-[120px]\"\n />\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Repeat Interval (ms):</label>\n <input \n v-model=\"newTask.repeatInterval\" \n type=\"number\" \n min=\"0\"\n step=\"1000\"\n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"0 for no repetition\"\n >\n <p class=\"text-xs text-content-tertiary mt-1\">Enter 0 or leave empty for no repetition. Use 1000 for 1 second, 60000 for 1 minute, etc.</p>\n </div>\n \n <div class=\"flex gap-2 pt-4\">\n <button \n @click=\"createTask\" \n class=\"flex-1 bg-primary text-primary-text px-4 py-2 rounded-md hover:bg-primary-hover\"\n >\n Create Task\n </button>\n <button \n @click=\"closeCreateTaskModal\" \n class=\"flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400\"\n >\n Cancel\n </button>\n </div>\n </div>\n </template>\n </modal>\n</div>\n";
|
|
51524
|
+
module.exports = "<div class=\"p-4 space-y-6\">\n <div>\n <h1 class=\"text-2xl font-bold text-content-secondary mb-4\">Task Overview</h1>\n <div v-if=\"status == 'init'\">\n <img src=\"images/loader.gif\" />\n </div>\n <!-- Task List -->\n <div class=\"bg-surface p-4 rounded-lg shadow\" v-if=\"status == 'loaded'\">\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Filter by Date:</label>\n <select v-model=\"selectedRange\" @change=\"updateDateRange\" class=\"border-edge-strong rounded-md shadow-sm w-full p-2\">\n <option v-for=\"option in dateFilters\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Filter by Status:</label>\n <select v-model=\"selectedStatus\" @change=\"getTasks\" class=\"border-edge-strong rounded-md shadow-sm w-full p-2\">\n <option v-for=\"option in statusFilters\" :key=\"option.value\" :value=\"option.value\">\n {{ option.label }}\n </option>\n </select>\n </div>\n <div class=\"mb-4\">\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Search by Task Name:</label>\n <input \n v-model=\"searchQuery\" \n type=\"text\" \n @input=\"onSearchInput\"\n class=\"border-edge-strong rounded-md shadow-sm w-full p-2\"\n placeholder=\"Enter task name to search...\"\n >\n </div>\n <div class=\"mb-4\">\n <button\n @click=\"resetFilters\"\n class=\"w-full bg-gray-200 text-content-secondary hover:bg-gray-300 font-medium py-2 px-4 rounded-md transition\"\n >\n Reset Filters\n </button>\n </div>\n <div class=\"mb-6\">\n <button\n @click=\"openCreateTaskModal\"\n class=\"w-full bg-primary text-primary-text hover:bg-primary-hover font-medium py-2 px-4 rounded-md transition\"\n >\n Create New Task\n </button>\n </div>\n <!-- Summary Section -->\n <div class=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n <button \n @click=\"setStatusFilter('pending')\"\n :class=\"getStatusColor('pending') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-yellow-200 hover:border-yellow-300'\"\n >\n <div class=\"text-sm\">Scheduled</div>\n <div class=\"text-2xl font-bold\">{{pendingCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('succeeded')\"\n :class=\"getStatusColor('succeeded') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-green-200 hover:border-green-300'\"\n >\n <div class=\"text-sm\">Completed</div>\n <div class=\"text-2xl font-bold\">{{succeededCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('failed')\"\n :class=\"getStatusColor('failed') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-red-200 hover:border-red-300'\"\n >\n <div class=\"text-sm\">Failed</div>\n <div class=\"text-2xl font-bold\">{{failedCount}}</div>\n </button>\n <button \n @click=\"setStatusFilter('cancelled')\"\n :class=\"getStatusColor('cancelled') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-edge hover:border-edge-strong'\"\n >\n <div class=\"text-sm\">Cancelled</div>\n <div class=\"text-2xl font-bold\">{{cancelledCount}}</div>\n </button>\n </div>\n\n <!-- Tasks Over Time Chart -->\n <!--\n Canvas is gated by showOverTimeChart (v-if) so Chart.js is destroyed\n and the DOM node is removed before each refresh. In-place Chart.js\n updates during Vue re-renders from filter changes could freeze the UI\n (dropdowns stuck, chart not updating). See tasks.js getTasks().\n -->\n <div class=\"mt-6\">\n <h2 class=\"text-lg font-semibold text-content-secondary mb-3\">Tasks Over Time</h2>\n <div class=\"bg-page border border-edge rounded-lg p-4\" style=\"height: 260px;\">\n <canvas v-if=\"showOverTimeChart && overTimeBuckets.length > 0\" ref=\"overTimeChart\" style=\"width:100%;height:100%;\"></canvas>\n <div v-else class=\"flex items-center justify-center h-full text-content-tertiary text-sm\">\n No task activity in the selected window\n </div>\n </div>\n </div>\n \n <!-- Grouped Task List -->\n <div class=\"mt-6\">\n <h2 class=\"text-lg font-semibold text-content-secondary mb-4\">Tasks by Name</h2>\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4\">\n <div v-for=\"group in tasksByName\" :key=\"group.name\" class=\"border border-edge rounded-lg p-4 group hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200\">\n <div class=\"flex items-start justify-between mb-3\">\n <div class=\"flex-1 cursor-pointer min-w-0 mr-2\" @click=\"openTaskGroupDetails(group)\">\n <div class=\"flex items-center gap-1\">\n <div class=\"font-medium text-sm group-hover:text-primary transition-colors truncate\">{{ group.name }}</div>\n <svg class=\"w-3 h-3 text-gray-400 group-hover:text-primary transition-colors flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"></path>\n </svg>\n </div>\n <div class=\"text-xs text-content-tertiary\">Total: {{ group.totalCount }} tasks</div>\n </div>\n <div class=\"text-xs text-content-tertiary flex-shrink-0\">\n {{ group.lastRun ? new Date(group.lastRun).toLocaleString() : 'Never' }}\n </div>\n </div>\n \n <!-- Status Counts -->\n <div class=\"grid grid-cols-2 gap-1.5\">\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'pending')\"\n class=\"bg-yellow-50 border border-yellow-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-yellow-300\"\n >\n <div class=\"text-xs text-yellow-600 font-medium\">Pending</div>\n <div class=\"text-base font-bold text-yellow-700\">{{ group.statusCounts.pending || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'succeeded')\"\n class=\"bg-green-50 border border-green-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-green-300\"\n >\n <div class=\"text-xs text-green-600 font-medium\">Succeeded</div>\n <div class=\"text-base font-bold text-green-700\">{{ group.statusCounts.succeeded || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'failed')\"\n class=\"bg-red-50 border border-red-200 rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-red-300\"\n >\n <div class=\"text-xs text-red-600 font-medium\">Failed</div>\n <div class=\"text-base font-bold text-red-700\">{{ group.statusCounts.failed || 0 }}</div>\n </button>\n <button \n @click.stop=\"openTaskGroupDetailsWithFilter(group, 'cancelled')\"\n class=\"bg-page border border-edge rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-edge-strong\"\n >\n <div class=\"text-xs text-gray-600 font-medium\">Cancelled</div>\n <div class=\"text-base font-bold text-content-secondary\">{{ group.statusCounts.cancelled || 0 }}</div>\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Create Task Modal -->\n <modal v-if=\"showCreateTaskModal\" containerClass=\"!h-[90vh] !w-[90vw]\">\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"closeCreateTaskModal\" role=\"button\" aria-label=\"Close modal\">×</div>\n <div class=\"space-y-4\">\n <h3 class=\"text-lg font-semibold text-content-secondary mb-4\">Create New Task</h3>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Task Name:</label>\n <input \n v-model=\"newTask.name\" \n type=\"text\" \n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Enter task name\"\n >\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Scheduled Time:</label>\n <input \n v-model=\"newTask.scheduledAt\" \n type=\"datetime-local\" \n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Parameters (JSON):</label>\n <ace-editor\n v-model=\"newTask.parameters\"\n mode=\"json\"\n :line-numbers=\"true\"\n class=\"min-h-[120px]\"\n />\n </div>\n \n <div>\n <label class=\"block text-sm font-medium text-content-secondary mb-1\">Repeat Interval (ms):</label>\n <input \n v-model=\"newTask.repeatInterval\" \n type=\"number\" \n min=\"0\"\n step=\"1000\"\n class=\"w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"0 for no repetition\"\n >\n <p class=\"text-xs text-content-tertiary mt-1\">Enter 0 or leave empty for no repetition. Use 1000 for 1 second, 60000 for 1 minute, etc.</p>\n </div>\n \n <div class=\"flex gap-2 pt-4\">\n <button \n @click=\"createTask\" \n class=\"flex-1 bg-primary text-primary-text px-4 py-2 rounded-md hover:bg-primary-hover\"\n >\n Create Task\n </button>\n <button \n @click=\"closeCreateTaskModal\" \n class=\"flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400\"\n >\n Cancel\n </button>\n </div>\n </div>\n </template>\n </modal>\n</div>\n";
|
|
50826
51525
|
|
|
50827
51526
|
/***/ },
|
|
50828
51527
|
|
|
@@ -62136,7 +62835,7 @@ var src_default = VueToastificationPlugin;
|
|
|
62136
62835
|
(module) {
|
|
62137
62836
|
|
|
62138
62837
|
"use strict";
|
|
62139
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.3.
|
|
62838
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.3.7","description":"A Mongoose-native MongoDB UI with schema-aware autocomplete, AI-assisted queries, and dashboards that understand your models - not just your data.","homepage":"https://mongoosestudio.app/","repository":{"type":"git","url":"https://github.com/mongoosejs/studio"},"license":"Apache-2.0","dependencies":{"@ai-sdk/anthropic":"2.x","@ai-sdk/google":"2.x","@ai-sdk/openai":"2.x","ace-builds":"^1.43.6","ai":"5.x","archetype":"0.13.1","csv-stringify":"6.3.0","ejson":"^2.2.3","extrovert":"^0.2.0","marked":"15.0.12","node-inspect-extracted":"3.x","regexp.escape":"^2.0.1","tailwindcss":"3.4.0","vue":"3.x","vue-toastification":"^2.0.0-rc.5","webpack":"5.x","time-commando":"1.0.1","xss":"^1.0.15"},"peerDependencies":{"mongoose":"7.x || 8.x || ^9.0.0"},"optionalPeerDependencies":{"@mongoosejs/task":"0.5.x || 0.6.x"},"devDependencies":{"@masteringjs/eslint-config":"0.1.1","axios":"1.2.2","dedent":"^1.6.0","eslint":"9.30.0","express":"4.x","mocha":"10.2.0","mongodb-memory-server":"^11.0.1","mongoose":"9.x","sinon":"^21.0.1"},"scripts":{"lint":"eslint .","seed":"node seed/index.js","start":"node ./local.js","tailwind":"tailwindcss -o ./frontend/public/tw.css","tailwind:watch":"tailwindcss -o ./frontend/public/tw.css --watch","test":"mocha test/*.test.js","test:frontend":"mocha test/frontend/*.test.js"}}');
|
|
62140
62839
|
|
|
62141
62840
|
/***/ }
|
|
62142
62841
|
|