@ozdao/martyrs 0.2.590 → 0.2.591
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/dist/builder.js +3 -0
- package/dist/{main-BIf-WirR.js → main-DQm5pwFO.js} +370 -364
- package/dist/martyrs/dist/{main-BIf-WirR.js → main-DQm5pwFO.js} +14 -14
- package/dist/martyrs/dist/{main-BIf-WirR.js.map → main-DQm5pwFO.js.map} +1 -1
- package/dist/martyrs/dist/{web-O7lXcjg0.js → web-n_ivHO3v.js} +2 -2
- package/dist/martyrs/dist/{web-O7lXcjg0.js.map → web-n_ivHO3v.js.map} +1 -1
- package/dist/martyrs/src/components/Button/{Button.vue.js → Button.vue2.js} +2 -2
- package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue2.js → Dropdown.vue.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +1 -0
- package/dist/martyrs/src/components/Feed/Carousel.vue.js +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -2
- package/dist/martyrs/src/components/FieldBig/FieldBig.vue.js +1 -1
- package/dist/martyrs/src/components/Loader/{Loader.vue2.js → Loader.vue.js} +2 -2
- package/dist/martyrs/src/components/Loader/Loader.vue.js.map +1 -0
- package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js +1 -1
- package/dist/martyrs/src/components/Media/Media.vue.js +1 -1
- package/dist/martyrs/src/components/Popup/Popup.vue.js +8 -2
- package/dist/martyrs/src/components/Popup/Popup.vue.js.map +1 -1
- package/dist/martyrs/src/components/Spoiler/{Spoiler.vue.js → Spoiler.vue2.js} +2 -2
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Tab/{Tab.vue.js → Tab.vue2.js} +2 -2
- package/dist/martyrs/src/components/Tab/Tab.vue2.js.map +1 -0
- package/dist/martyrs/src/components/UploadImage/UploadImage.vue.js +1 -1
- package/dist/martyrs/src/components/UploadImageMultiple/UploadImageMultiple.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/auth.client.js +6 -0
- package/dist/martyrs/src/modules/auth/auth.client.js.map +1 -1
- package/dist/martyrs/src/modules/auth/locales/en.js +7 -0
- package/dist/martyrs/src/modules/auth/locales/en.js.map +1 -1
- package/dist/martyrs/src/modules/auth/locales/ru.js +7 -0
- package/dist/martyrs/src/modules/auth/locales/ru.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/blocks/OtpDialog.vue.js +1 -1
- package/dist/martyrs/src/modules/{core → auth}/views/components/blocks/PopupAuth.vue.js +14 -10
- package/dist/martyrs/src/modules/auth/views/components/blocks/PopupAuth.vue.js.map +1 -0
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditAccount.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileEditProfile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +2 -2
- package/dist/martyrs/src/modules/{core → auth}/views/plugins/popup.auth.plugin.js +21 -8
- package/dist/martyrs/src/modules/auth/views/plugins/popup.auth.plugin.js.map +1 -0
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +1 -1
- package/dist/martyrs/src/modules/core/core.client.js +0 -2
- package/dist/martyrs/src/modules/core/core.client.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/CardHeader.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/blocks/PopupDateSelector.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js +48 -12
- package/dist/martyrs/src/modules/core/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js +11 -5
- package/dist/martyrs/src/modules/core/views/components/partials/Header.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Navigation.vue.js +2 -2
- package/dist/martyrs/src/modules/core/views/components/partials/NavigationBar.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/components/partials/Sidebar.vue.js +3 -3
- package/dist/martyrs/src/modules/core/views/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonCheck.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/elements/ButtonJoin.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/EditTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/Feed.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/sections/List.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/landing/components/sections/SectionGuide.vue.js +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/sections/SectionMenu.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/blocks/ActionButtons.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/cards/AlbumCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/ArtistCardSmall.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/PlaylistCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/cards/TrackListCard.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/forms/PlaylistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/SearchForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/pages/Artist.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/MusicLibrary.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/pages/SearchResults.vue.js +2 -2
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +3 -3
- package/dist/martyrs/src/modules/music/components/pages/TrackCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/FullscreenPlayer.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/MusicPlayer.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/PlayerControls.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/player/VolumeControl.vue.js +1 -1
- package/dist/martyrs/src/modules/notifications/components/sections/NotificationPreferences.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormSelectCustomer.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreate.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/ApplicationDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/CustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +4 -4
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Documents.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +2 -2
- package/dist/martyrs/src/modules/pages/views/components/blocks/CardPage.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/pages/PageEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/pages/views/components/partials/SidebarPages.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/elements/Image360.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditAttributes.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/FilterProducts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductConfigurator.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsRecommended.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +2 -2
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +3 -3
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Spot.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/style.css +15 -8
- package/dist/{web-O7lXcjg0.js → web-n_ivHO3v.js} +1 -1
- package/package.json +1 -1
- package/src/builder/modes/ssr.rspack.dev.js +2 -1
- package/src/builder/rspack/rspack.config.base.js +3 -0
- package/src/components/Popup/Popup.vue +6 -2
- package/src/modules/auth/auth.client.js +8 -0
- package/src/modules/auth/locales/en.js +7 -0
- package/src/modules/auth/locales/ru.js +7 -0
- package/src/modules/auth/views/components/blocks/PopupAuth.vue +72 -0
- package/src/modules/auth/views/components/pages/ProfileEdit.old.vue +1 -1
- package/src/modules/auth/views/plugins/popup.auth.plugin.js +91 -0
- package/src/modules/core/core.client.js +0 -2
- package/src/modules/core/views/components/layouts/Client.vue +66 -10
- package/src/modules/core/views/components/partials/Header.vue +29 -11
- package/src/modules/core/views/components/partials/Sidebar.vue +2 -2
- package/dist/martyrs/src/components/Button/Button.vue.js.map +0 -1
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +0 -1
- package/dist/martyrs/src/components/Spoiler/Spoiler.vue.js.map +0 -1
- package/dist/martyrs/src/components/Tab/Tab.vue.js.map +0 -1
- package/dist/martyrs/src/modules/core/views/components/blocks/PopupAuth.vue.js.map +0 -1
- package/dist/martyrs/src/modules/core/views/plugins/popup.auth.plugin.js.map +0 -1
|
@@ -6,6 +6,7 @@ console.log('[LOADING 36] Auth module import started...');
|
|
|
6
6
|
import * as storeAuth from './views/store/auth.js';
|
|
7
7
|
import * as storeUsers from './views/store/users.js';
|
|
8
8
|
import otpPlugin from './views/plugins/otp.plugin.js';
|
|
9
|
+
import popupAuthPlugin, { showAuth, closeAuth, cancelAuth } from './views/plugins/popup.auth.plugin.js';
|
|
9
10
|
|
|
10
11
|
performance.mark('loading-36-stores-end');
|
|
11
12
|
const storesTime = performance.measure('loading-36-stores', 'loading-36-start', 'loading-36-stores-end');
|
|
@@ -54,6 +55,9 @@ function initializeAuth(app, store, router, options = {}) {
|
|
|
54
55
|
// OTP plugin для challenge-response
|
|
55
56
|
app.use(otpPlugin);
|
|
56
57
|
|
|
58
|
+
// Auth popup plugin
|
|
59
|
+
app.use(popupAuthPlugin);
|
|
60
|
+
|
|
57
61
|
app.provide('store', store);
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -82,6 +86,10 @@ export {
|
|
|
82
86
|
getUsersRoutes,
|
|
83
87
|
validationAuth,
|
|
84
88
|
initializeAuth as initialize,
|
|
89
|
+
// Auth popup
|
|
90
|
+
showAuth,
|
|
91
|
+
closeAuth,
|
|
92
|
+
cancelAuth,
|
|
85
93
|
};
|
|
86
94
|
|
|
87
95
|
// [LOADING 36] Auth module import completed
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// @martyrs/src/modules/auth/locales/en.js
|
|
2
2
|
export default {
|
|
3
3
|
auth: {
|
|
4
|
+
popup: {
|
|
5
|
+
title: "Welcome",
|
|
6
|
+
subtitle: "Please sign in or create an account to continue.",
|
|
7
|
+
signUp: "Sign Up",
|
|
8
|
+
haveAccount: "Already have an account?",
|
|
9
|
+
signIn: "Sign in"
|
|
10
|
+
},
|
|
4
11
|
signIn: {
|
|
5
12
|
title: "Welcome to OZ DAO,",
|
|
6
13
|
subtitle: "Sign In to Continue",
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// @martyrs/src/modules/auth/locales/ru.js
|
|
2
2
|
export default {
|
|
3
3
|
auth: {
|
|
4
|
+
popup: {
|
|
5
|
+
title: "Добро пожаловать",
|
|
6
|
+
subtitle: "Войдите или создайте аккаунт для продолжения.",
|
|
7
|
+
signUp: "Регистрация",
|
|
8
|
+
haveAccount: "Уже есть аккаунт?",
|
|
9
|
+
signIn: "Войти"
|
|
10
|
+
},
|
|
4
11
|
signIn: {
|
|
5
12
|
title: "Приветствуем вас,",
|
|
6
13
|
subtitle: "Войдите для продолжения",
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!-- @martyrs/src/modules/auth/views/components/AuthDialog.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<Popup
|
|
4
|
+
:isPopupOpen="authState.visible"
|
|
5
|
+
@close-popup="closeAuth"
|
|
6
|
+
@after-leave="$emit('after-leave')"
|
|
7
|
+
class="bg-white radius-medium pd-medium"
|
|
8
|
+
>
|
|
9
|
+
<div class="t-center">
|
|
10
|
+
<img loading="lazy" :src="'/logo/logo.svg'" class="i-extra radius-small mn-b-medium">
|
|
11
|
+
<h3 class="mn-b-medium">{{ authState.title || t('auth.popup.title') }}</h3>
|
|
12
|
+
<p class="mn-b-semi t-transp">{{ authState.subtitle || t('auth.popup.subtitle') }}</p>
|
|
13
|
+
|
|
14
|
+
<div class="flex-column flex gap-thin">
|
|
15
|
+
<Button
|
|
16
|
+
:submit="handleSignUp"
|
|
17
|
+
class="bg-main radius-small mn-b-small pd-thin"
|
|
18
|
+
>
|
|
19
|
+
{{ authState.buttonText || t('auth.popup.signUp') }}
|
|
20
|
+
</Button>
|
|
21
|
+
|
|
22
|
+
<span>
|
|
23
|
+
{{ t('auth.popup.haveAccount') }}
|
|
24
|
+
<a @click="handleSignIn" class="t-grey cursor-pointer">{{ t('auth.popup.signIn') }}</a>
|
|
25
|
+
</span>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</Popup>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup>
|
|
32
|
+
import { useRouter, useRoute } from 'vue-router';
|
|
33
|
+
import { useI18n } from 'vue-i18n';
|
|
34
|
+
import Popup from '@martyrs/src/components/Popup/Popup.vue';
|
|
35
|
+
import Button from '@martyrs/src/components/Button/Button.vue';
|
|
36
|
+
|
|
37
|
+
const { t } = useI18n();
|
|
38
|
+
|
|
39
|
+
defineEmits(['after-leave']);
|
|
40
|
+
|
|
41
|
+
const props = defineProps({
|
|
42
|
+
authState: {
|
|
43
|
+
type: Object,
|
|
44
|
+
required: true
|
|
45
|
+
},
|
|
46
|
+
closeAuth: {
|
|
47
|
+
type: Function,
|
|
48
|
+
required: true
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const router = useRouter();
|
|
53
|
+
const route = useRoute();
|
|
54
|
+
|
|
55
|
+
const handleSignIn = async () => {
|
|
56
|
+
const returnUrl = props.authState.returnUrl || route.fullPath;
|
|
57
|
+
await router.push({
|
|
58
|
+
name: 'Sign In',
|
|
59
|
+
query: { returnUrl }
|
|
60
|
+
});
|
|
61
|
+
props.closeAuth('signin');
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const handleSignUp = async () => {
|
|
65
|
+
const returnUrl = props.authState.returnUrl || route.fullPath;
|
|
66
|
+
await router.push({
|
|
67
|
+
name: 'Sign Up',
|
|
68
|
+
query: { returnUrl }
|
|
69
|
+
});
|
|
70
|
+
props.closeAuth('signup');
|
|
71
|
+
};
|
|
72
|
+
</script>
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<h3 class="mn-b-small">Settings</h3>
|
|
94
94
|
<Checkbox
|
|
95
95
|
:label="'Darkmode'"
|
|
96
|
-
:radio="core.state.theme.
|
|
96
|
+
:radio="core.state.theme.mode === 'dark'"
|
|
97
97
|
@update:radio="event => core.actions.toggleTheme()"
|
|
98
98
|
class="w-100 bg-light t-black pd-medium radius-small"
|
|
99
99
|
/>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// @martyrs/src/modules/auth/views/plugins/authPlugin.js
|
|
2
|
+
import { reactive, defineComponent, h, render, defineAsyncComponent, nextTick } from 'vue';
|
|
3
|
+
|
|
4
|
+
// Dynamic import for better tree shaking and lazy loading
|
|
5
|
+
const PopupAuth = defineAsyncComponent(() =>
|
|
6
|
+
import('@martyrs/src/modules/auth/views/components/blocks/PopupAuth.vue')
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
// 1) Общее состояние и API
|
|
10
|
+
const state = reactive({
|
|
11
|
+
shouldRender: false, // контролирует рендеринг компонента
|
|
12
|
+
visible: false, // контролирует анимацию
|
|
13
|
+
title: '',
|
|
14
|
+
subtitle: '',
|
|
15
|
+
buttonText: '',
|
|
16
|
+
returnUrl: '',
|
|
17
|
+
resolve: null,
|
|
18
|
+
reject: null
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export function showAuth({
|
|
22
|
+
title = '',
|
|
23
|
+
subtitle = '',
|
|
24
|
+
buttonText = '',
|
|
25
|
+
returnUrl = ''
|
|
26
|
+
} = {}) {
|
|
27
|
+
return new Promise((res, rej) => {
|
|
28
|
+
state.resolve = res;
|
|
29
|
+
state.reject = rej;
|
|
30
|
+
state.title = title;
|
|
31
|
+
state.subtitle = subtitle;
|
|
32
|
+
state.buttonText = buttonText;
|
|
33
|
+
state.returnUrl = returnUrl;
|
|
34
|
+
state.shouldRender = true;
|
|
35
|
+
nextTick(() => { state.visible = true; });
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function closeAuth(result = null) {
|
|
40
|
+
state.visible = false;
|
|
41
|
+
state.resolve?.(result);
|
|
42
|
+
state.resolve = state.reject = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function cancelAuth() {
|
|
46
|
+
state.visible = false;
|
|
47
|
+
state.reject?.(new Error('Authentication cancelled'));
|
|
48
|
+
state.resolve = state.reject = null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function onAfterLeave() {
|
|
52
|
+
state.shouldRender = false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 2) Хост-компонент
|
|
56
|
+
const AuthDialogHost = defineComponent({
|
|
57
|
+
name: 'AuthDialogHost',
|
|
58
|
+
setup() {
|
|
59
|
+
return () => {
|
|
60
|
+
if (!state.shouldRender) return null;
|
|
61
|
+
|
|
62
|
+
return h(PopupAuth, {
|
|
63
|
+
authState: state,
|
|
64
|
+
closeAuth: closeAuth,
|
|
65
|
+
'onClose-popup': cancelAuth,
|
|
66
|
+
'onAfter-leave': onAfterLeave
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 3) Плагин
|
|
73
|
+
export default {
|
|
74
|
+
install(app) {
|
|
75
|
+
// 3.1) Глобальный метод
|
|
76
|
+
app.config.globalProperties.$auth = showAuth;
|
|
77
|
+
app.config.globalProperties.$showAuth = showAuth;
|
|
78
|
+
|
|
79
|
+
// 3.2) Контейнер в body
|
|
80
|
+
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
81
|
+
const container = document.createElement('div');
|
|
82
|
+
container.id = 'auth-dialog-host';
|
|
83
|
+
document.body.appendChild(container);
|
|
84
|
+
|
|
85
|
+
// 3.3) Рендерим VNode в контексте основного app
|
|
86
|
+
const vnode = h(AuthDialogHost);
|
|
87
|
+
vnode.appContext = app._context; // <-- ключевой момент
|
|
88
|
+
render(vnode, container);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
@@ -9,7 +9,6 @@ import * as appRenderer from './views/utils/vue-app-renderer.js';
|
|
|
9
9
|
import './views/utils/polyfills.js'; // Auto-apply polyfills
|
|
10
10
|
|
|
11
11
|
import alertPlugin from './views/plugins/alert.plugin.js';
|
|
12
|
-
import popupAuthPlugin from './views/plugins/popup.auth.plugin.js';
|
|
13
12
|
import datePickerPlugin from './views/plugins/date-picker.plugin.js';
|
|
14
13
|
import storeDebuggerPlugin from './views/plugins/store-debugger/store-debugger.plugin.js';
|
|
15
14
|
|
|
@@ -50,7 +49,6 @@ function initializeCore(app, store, router, config, options = {}) {
|
|
|
50
49
|
app.mixin(mixins.globalMixins);
|
|
51
50
|
|
|
52
51
|
app.use(alertPlugin);
|
|
53
|
-
app.use(popupAuthPlugin);
|
|
54
52
|
app.use(datePickerPlugin);
|
|
55
53
|
// app.use(storeDebuggerPlugin, store);
|
|
56
54
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
<component class="tab" :is="route.meta.walkthrough" name="Walkthrough" @updateFirstUse="updateFirstUse" :slides="[1, 2, 3]"> </component>
|
|
19
19
|
</section>
|
|
20
20
|
</transition>
|
|
21
|
+
|
|
21
22
|
<transition name="moveFromTop" mode="out-in">
|
|
22
23
|
<Status class="z-index-10" v-if="store.core.state.error.show" :data="store.core.state.error" @close="store.core.state.error.show = false" />
|
|
23
24
|
</transition>
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
/>
|
|
34
35
|
</transition>
|
|
35
36
|
|
|
37
|
+
|
|
36
38
|
<component
|
|
37
39
|
v-if="!MOBILE_APP && route.meta.header"
|
|
38
40
|
ref="header"
|
|
@@ -40,9 +42,7 @@
|
|
|
40
42
|
:theme="headerTheme"
|
|
41
43
|
:logotype="route.meta.logotype"
|
|
42
44
|
:location="route.meta.location"
|
|
43
|
-
:
|
|
44
|
-
'header-scrolled': scrollOffset > 50,
|
|
45
|
-
}"
|
|
45
|
+
:headerClass="computedHeaderClass"
|
|
46
46
|
>
|
|
47
47
|
<component
|
|
48
48
|
v-if="route.meta?.header_navigation"
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
/>
|
|
55
55
|
</component>
|
|
56
56
|
|
|
57
|
+
|
|
57
58
|
<transition name="moveFromTop" mode="out-in" appear>
|
|
58
59
|
<component
|
|
59
60
|
v-if="MOBILE_APP && !route.meta.hideNavigationBar"
|
|
@@ -250,19 +251,74 @@ function scrollTop() {
|
|
|
250
251
|
}
|
|
251
252
|
// Scrolling header
|
|
252
253
|
const scrollOffset = ref(0);
|
|
253
|
-
let isScrolled = false;
|
|
254
254
|
const header = ref(null);
|
|
255
255
|
|
|
256
|
+
// Режим → классы позиционирования
|
|
257
|
+
const modeClasses = {
|
|
258
|
+
static: 'pos-relative',
|
|
259
|
+
sticky: 'pos-sticky pos-t-0',
|
|
260
|
+
fixed: 'pos-fixed pos-t-0 w-100',
|
|
261
|
+
overlay: 'pos-absolute pos-t-0 w-100'
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// isScrolled
|
|
265
|
+
const isScrolled = computed(() =>
|
|
266
|
+
scrollOffset.value > (route.meta.header_scroll_threshold ?? 50)
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
// headerTheme с учётом скролла
|
|
256
270
|
const headerTheme = computed(() => {
|
|
257
|
-
if (
|
|
258
|
-
return route.meta.
|
|
259
|
-
} else {
|
|
260
|
-
return route.meta.header_theme || 'light';
|
|
271
|
+
if (isScrolled.value && route.meta.header_scroll_theme) {
|
|
272
|
+
return route.meta.header_scroll_theme;
|
|
261
273
|
}
|
|
274
|
+
return route.meta.header_theme || 'light';
|
|
262
275
|
});
|
|
263
276
|
|
|
264
|
-
|
|
265
|
-
|
|
277
|
+
// headerModeClass (overlay → fixed после скролла)
|
|
278
|
+
const headerModeClass = computed(() => {
|
|
279
|
+
const mode = route.meta.header_mode || 'static';
|
|
280
|
+
if (mode === 'overlay' && isScrolled.value) {
|
|
281
|
+
return 'pos-fixed pos-t-0 w-100';
|
|
282
|
+
}
|
|
283
|
+
return modeClasses[mode];
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// headerAppearanceClass
|
|
287
|
+
const headerAppearanceClass = computed(() => {
|
|
288
|
+
const config = isScrolled.value
|
|
289
|
+
? route.meta.header_scroll_class
|
|
290
|
+
: route.meta.header_class;
|
|
291
|
+
|
|
292
|
+
if (config && typeof config === 'object') {
|
|
293
|
+
return config[headerTheme.value];
|
|
294
|
+
}
|
|
295
|
+
return config;
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Autohide
|
|
299
|
+
const isHidden = ref(false);
|
|
300
|
+
let lastScrollY = 0;
|
|
301
|
+
|
|
302
|
+
// computedHeaderClass для передачи в Header
|
|
303
|
+
const computedHeaderClass = computed(() => [
|
|
304
|
+
headerModeClass.value,
|
|
305
|
+
headerAppearanceClass.value,
|
|
306
|
+
{ 'header--hidden': isHidden.value }
|
|
307
|
+
]);
|
|
308
|
+
|
|
309
|
+
const handleScroll = (event) => {
|
|
310
|
+
const scrollY = event.target.scrollTop;
|
|
311
|
+
scrollOffset.value = scrollY;
|
|
312
|
+
|
|
313
|
+
// Autohide логика
|
|
314
|
+
if (route.meta.header_autohide) {
|
|
315
|
+
if (scrollY > lastScrollY && scrollY > 200) {
|
|
316
|
+
isHidden.value = true;
|
|
317
|
+
} else if (scrollY < lastScrollY) {
|
|
318
|
+
isHidden.value = false;
|
|
319
|
+
}
|
|
320
|
+
lastScrollY = scrollY;
|
|
321
|
+
}
|
|
266
322
|
};
|
|
267
323
|
/////////////////////////////
|
|
268
324
|
// FIRST USE
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
type: Boolean,
|
|
40
40
|
default: true
|
|
41
41
|
},
|
|
42
|
+
headerClass: {
|
|
43
|
+
type: [String, Array, Object],
|
|
44
|
+
default: null
|
|
45
|
+
},
|
|
42
46
|
});
|
|
43
47
|
// Accessing state
|
|
44
48
|
const router = useRouter()
|
|
@@ -59,24 +63,24 @@
|
|
|
59
63
|
</script>
|
|
60
64
|
|
|
61
65
|
<template>
|
|
62
|
-
<header
|
|
63
|
-
id="header"
|
|
66
|
+
<header
|
|
67
|
+
id="header"
|
|
64
68
|
class="
|
|
65
|
-
pd-thin
|
|
69
|
+
pd-thin
|
|
66
70
|
gap-micro
|
|
67
71
|
flex-justify-between
|
|
68
72
|
flex-nowrap
|
|
69
73
|
flex
|
|
70
74
|
h-4r
|
|
71
75
|
w-100
|
|
72
|
-
z-index-2
|
|
73
|
-
pos-relative pos-t-0
|
|
74
|
-
br-b-1px
|
|
76
|
+
z-index-2
|
|
75
77
|
"
|
|
76
|
-
:class="
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
:class="[
|
|
79
|
+
headerClass ?? {
|
|
80
|
+
'pos-relative pos-t-0 br-b-1px t-black br-light': theme === 'light',
|
|
81
|
+
'pos-relative pos-t-0 br-b-1px t-white br-dark': theme === 'dark'
|
|
82
|
+
}
|
|
83
|
+
]"
|
|
80
84
|
>
|
|
81
85
|
<div class="flex-nowrap flex-v-center flex-justify-start flex gap-micro ">
|
|
82
86
|
<!-- MENU -->
|
|
@@ -213,7 +217,21 @@
|
|
|
213
217
|
</template>
|
|
214
218
|
|
|
215
219
|
<style lang="scss">
|
|
216
|
-
|
|
220
|
+
#header {
|
|
221
|
+
transition:
|
|
222
|
+
transform 0.3s cubic-bezier(0.08, 0.75, 0.77, 1.03),
|
|
223
|
+
margin-top 0.3s cubic-bezier(0.08, 0.75, 0.77, 1.03),
|
|
224
|
+
background 0.3s ease,
|
|
225
|
+
border-color 0.3s ease,
|
|
226
|
+
backdrop-filter 0.3s ease;
|
|
227
|
+
|
|
228
|
+
&.header--hidden {
|
|
229
|
+
transform: translateY(-100%);
|
|
230
|
+
margin-top: -4rem;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.location-button {
|
|
217
235
|
&:hover {
|
|
218
236
|
box-shadow: inset 0 0 0 2px rgb(var(--main));
|
|
219
237
|
}
|
|
@@ -86,7 +86,7 @@ router.beforeEach((to, from) => {
|
|
|
86
86
|
<template>
|
|
87
87
|
<aside
|
|
88
88
|
data-sidebar
|
|
89
|
-
class="ease-quint-out w-min-0 flex-child-default z-index-2 br-r-1px flex flex-column h-100"
|
|
89
|
+
class="ease-quint-out w-min-0 o-hidden flex-child-default z-index-2 br-r-1px flex flex-column h-100"
|
|
90
90
|
:class="[
|
|
91
91
|
{ 'mobile-opened': isManuallyOpened },
|
|
92
92
|
stateSidebar
|
|
@@ -145,7 +145,7 @@ router.beforeEach((to, from) => {
|
|
|
145
145
|
Dark Mode
|
|
146
146
|
</span>
|
|
147
147
|
<span class="aspect-1x1 flex-child-default w-max-big w-100 flex flex-center ">
|
|
148
|
-
{{ store.core.state.theme.
|
|
148
|
+
{{ store.core.state.theme.mode === 'dark' ? '🌙' : '☀️' }}
|
|
149
149
|
</span>
|
|
150
150
|
</button>
|
|
151
151
|
</div>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Button.vue.js","sources":["../../../../../src/components/Button/Button.vue"],"sourcesContent":["<script setup>\nimport { ref } from 'vue'\n\nimport IconCheckmark from '@martyrs/src/modules/icons/navigation/IconCheckmark.vue';\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue';\n\nconst props = defineProps({\n submit: {\n type: Function,\n default: async () => { console.log('Button click.') }\n },\n text: {\n type: Object,\n default: () => ({\n success: null,\n error: null\n })\n },\n counter: {\n type: Object\n },\n callback: {\n type: Function,\n default: async () => { console.log('Button callback.') }\n },\n callbackDelay: {\n type: Number,\n default: 750\n },\n showSucces: {\n type: Boolean,\n default: true\n },\n showLoader: {\n type: Boolean,\n default: true\n },\n validation: {\n type: Boolean,\n default: false\n },\n})\n\nconst emits = defineEmits(['error'])\n\nconst button = ref(null)\nconst error = ref(null)\nconst loading = ref(false)\nconst finished = ref(false)\n\nasync function Submit() {\n console.log('click')\n \n button.value.style['pointer-events'] = 'none'\n error.value = null\n loading.value = true\n\n // Функция для сброса состояния кнопки\n const resetButton = () => {\n if (button.value) {\n button.value.style.pointerEvents = 'auto'\n loading.value = false\n finished.value = false\n error.value = null\n }\n }\n\n try {\n await props.submit()\n\n button.value.classList.replace('bg-main', 'bg-second')\n loading.value = false\n\n // Используем функцию сброса состояния кнопки здесь\n if (props.showSucces) { \n finished.value = true\n setTimeout(() => {\n resetButton()\n button.value.classList.replace('bg-second', 'bg-main')\n }, 500)\n } else {\n resetButton()\n button.value.classList.replace('bg-second', 'bg-main')\n }\n\n // Если есть callback, мы также установим таймер для его вызова\n if (props.callback) setTimeout(() => props.callback(), props.callbackDelay)\n\n } catch (err) {\n console.error('=== BUTTON ERROR ===', err)\n emits('error', err)\n // Если возникла ошибка, мы изменяем стили и устанавливаем сообщение об ошибке\n button.value.classList.replace('bg-main', 'bg-fourth-nano')\n loading.value = false\n error.value = true\n \n // После задержки снова сбрасываем состояние кнопки\n setTimeout(() => {\n resetButton()\n // Так как класс кнопки был изменен, вернем его в исходное состояние\n button.value.classList.replace('bg-fourth-nano', 'bg-main')\n }, 1330)\n }\n}\n</script>\n\n<template>\n <button \n @click.stop=\"Submit\"\n :disabled=\"validation\"\n ref=\"button\"\n\t\tclass=\"button\"\n :class=\"{ 'button--disabled': loading || validation }\"\n >\n <span class=\"button-content\" :class=\"{ 'hidden': loading || error || finished }\">\n <slot></slot>\n </span>\n\n <span class=\"button-loader\" :class=\"{ 'active': loading && showLoader }\">\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n <span class=\"dot\"></span>\n </span>\n\n <span class=\"button-success\" :class=\"{ 'active': finished && showSucces }\">\n <template v-if=\"text.success\">{{ text.success }}</template>\n <IconCheckmark v-else class=\"i-regular\" />\n </span>\n\n <span class=\"button-error\" :class=\"{ 'active': error }\">\n <template v-if=\"text.error\">{{ text.error }}</template>\n <IconCross v-else class=\"i-regular\" />\n </span>\n \n <!-- Counter -->\n <div v-if=\"counter\" class=\"button-counter font-second flex flex-center\">\n <span>{{ counter }}</span>\n </div>\n </button>\n</template>\n\n<style lang=\"scss\">\nbutton[disabled] {\n opacity: 0.75 !important;\n pointer-events: none !important;\n cursor: default !important;\n color: rgba(var(--dark), 0.33) !important;\n background: rgba(var(--light), 1) !important;\n}\n\na.button {\n text-box: trim-both cap alphabetic;\n}\n\n.button {\n position: relative;\n display: flex;\n padding: var(--small);\n border-radius: var(--small);\n text-box: trim-both cap alphabetic;\n transform: scale(1);\n opacity: 1;\n align-items: center;\n justify-content: center;\n color: black;\n text-align: center;\n font-size: 1rem;\n letter-spacing: 5%;\n transition: all 0.33s ease;\n\n &:hover {\n cursor: pointer;\n opacity: 0.9;\n }\n\n &:active {\n transform: scale(0.95);\n }\n\n &-small {\n padding: 0.75rem;\n border-radius: 0.5rem;\n height: fit-content;\n }\n\n .button-counter {\n position: absolute;\n right: -8px;\n bottom: -8px;\n background: yellow;\n height: 16px;\n border-radius: 16px;\n width: 16px;\n font-weight: 500;\n text-align: center;\n line-height: 16px;\n font-size: 10px;\n }\n}\n\n.button-content {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n transform: translateY(0);\n opacity: 1;\n transition:\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n\n &.hidden {\n opacity: 0;\n transform: translateY(4px);\n }\n}\n\n.button-loader {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n opacity: 0;\n transform: translateY(4px);\n transition:\n opacity 0.25s cubic-bezier(0.0, 0, 0.2, 1) 0.05s,\n transform 0.25s cubic-bezier(0.0, 0, 0.2, 1) 0.05s;\n pointer-events: none;\n\n &.active {\n opacity: 1;\n transform: translateY(0);\n }\n\n .dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n animation: dot-bounce 0.8s cubic-bezier(0.4, 0, 0.2, 1) infinite;\n\n &:nth-child(1) { animation-delay: 0s; }\n &:nth-child(2) { animation-delay: 0.12s; }\n &:nth-child(3) { animation-delay: 0.24s; }\n }\n}\n\n@keyframes dot-bounce {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-5px);\n }\n}\n\n.button-success {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transform: translateY(4px);\n transition:\n opacity 0.2s cubic-bezier(0.0, 0, 0.2, 1),\n transform 0.2s cubic-bezier(0.0, 0, 0.2, 1);\n pointer-events: none;\n\n &.active {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.button-error {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transform: translateY(4px);\n transition:\n opacity 0.2s cubic-bezier(0.0, 0, 0.2, 1),\n transform 0.2s cubic-bezier(0.0, 0, 0.2, 1);\n pointer-events: none;\n\n &.active {\n opacity: 1;\n transform: translateY(0);\n }\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,UAAM,QAAQ;AAqCd,UAAM,QAAQ;AAEd,UAAM,SAAS,IAAI,IAAI;AACvB,UAAM,QAAQ,IAAI,IAAI;AACtB,UAAM,UAAU,IAAI,KAAK;AACzB,UAAM,WAAW,IAAI,KAAK;AAE1B,mBAAe,SAAS;AACtB,cAAQ,IAAI,OAAO;AAEnB,aAAO,MAAM,MAAM,gBAAgB,IAAI;AACvC,YAAM,QAAQ;AACd,cAAQ,QAAQ;AAGhB,YAAM,cAAc,MAAM;AACxB,YAAI,OAAO,OAAO;AAChB,iBAAO,MAAM,MAAM,gBAAgB;AACnC,kBAAQ,QAAQ;AAChB,mBAAS,QAAQ;AACjB,gBAAM,QAAQ;AAAA,QAChB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,MAAM,OAAM;AAElB,eAAO,MAAM,UAAU,QAAQ,WAAW,WAAW;AACrD,gBAAQ,QAAQ;AAGhB,YAAI,MAAM,YAAY;AACpB,mBAAS,QAAQ;AACjB,qBAAW,MAAM;AACf,wBAAW;AACX,mBAAO,MAAM,UAAU,QAAQ,aAAa,SAAS;AAAA,UACvD,GAAG,GAAG;AAAA,QACR,OAAO;AACL,sBAAW;AACX,iBAAO,MAAM,UAAU,QAAQ,aAAa,SAAS;AAAA,QACvD;AAGA,YAAI,MAAM,SAAU,YAAW,MAAM,MAAM,SAAQ,GAAI,MAAM,aAAa;AAAA,MAE5E,SAAS,KAAK;AACZ,gBAAQ,MAAM,wBAAwB,GAAG;AACzC,cAAM,SAAS,GAAG;AAElB,eAAO,MAAM,UAAU,QAAQ,WAAW,gBAAgB;AAC1D,gBAAQ,QAAQ;AAChB,cAAM,QAAQ;AAGd,mBAAW,MAAM;AACf,sBAAW;AAEX,iBAAO,MAAM,UAAU,QAAQ,kBAAkB,SAAS;AAAA,QAC5D,GAAG,IAAI;AAAA,MACT;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.vue2.js","sources":["../../../../../src/components/Dropdown/Dropdown.vue"],"sourcesContent":["<template>\n <div\n class=\"dropdown pos-relative\"\n v-click-outside=\"clickedOutside\"\n @click.stop=\"trigger === 'click' ? (isOpen = !isOpen) : null\"\n @mouseenter=\"handleMouseEnter\"\n @mouseleave=\"handleMouseLeave\"\n >\n <slot name=\"label\">\n <div v-if=\"isComponentLabel\" class=\"w-100 h-100 flex-center flex\">\n <component :is=\"label.component\" v-bind=\"label.props\" :class=\"label.class\"></component>\n </div>\n <div v-else>\n {{ label }}\n </div>\n </slot>\n <Transition name=\"dropdown\">\n <div\n v-if=\"isOpen\"\n :style=\"{ left: align === 'left' ? '0' : 'auto', right: align === 'right' ? '0' : 'auto' }\"\n class=\"dropdown-content\"\n >\n <slot></slot>\n </div>\n </Transition>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed } from 'vue';\nimport clickOutside from '../FieldPhone/click-outside.js';\n\nlet vClickOutside = clickOutside\n\nconst props = defineProps({\n label: {\n type: [String, Object],\n default: 'Open'\n },\n align: {\n type: String,\n default: 'left'\n },\n trigger: {\n type: String,\n default: 'click'\n }\n})\n\nconst isOpen = ref(false);\nconst isComponentLabel = computed(() => typeof props.label === 'object');\n\nlet closeTimeout = null;\n\nfunction handleMouseEnter() {\n if (props.trigger === 'hover') {\n clearTimeout(closeTimeout);\n isOpen.value = true;\n }\n}\n\nfunction handleMouseLeave() {\n if (props.trigger === 'hover') {\n closeTimeout = setTimeout(() => {\n isOpen.value = false;\n }, 100);\n }\n}\n\nfunction clickedOutside() {\n if (props.trigger === 'click') {\n isOpen.value = false;\n }\n}\n</script>\n\n<style>\n.dropdown-content {\n position: absolute;\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n z-index: 100;\n border-radius: var(--small);\n transform-origin: top left;\n backdrop-filter: blur(var(--small));\n -webkit-backdrop-filter: blur(var(--small));\n background: rgba(var(--white), 0.5);\n}\n\n.dropdown-enter-active,\n.dropdown-leave-active {\n transition: transform 0.33s cubic-bezier(0.9, 0, 0.1, 1), opacity 0.15s ease;\n}\n\n.dropdown-enter-from,\n.dropdown-leave-to {\n opacity: 0.01;\n transform: translateY(-4px) scale(0.8);\n}\n</style>\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,QAAI,gBAAgB;AAEpB,UAAM,QAAQ;AAed,UAAM,SAAS,IAAI,KAAK;AACxB,UAAM,mBAAmB,SAAS,MAAM,OAAO,MAAM,UAAU,QAAQ;AAEvE,QAAI,eAAe;AAEnB,aAAS,mBAAmB;AAC1B,UAAI,MAAM,YAAY,SAAS;AAC7B,qBAAa,YAAY;AACzB,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAEA,aAAS,mBAAmB;AAC1B,UAAI,MAAM,YAAY,SAAS;AAC7B,uBAAe,WAAW,MAAM;AAC9B,iBAAO,QAAQ;AAAA,QACjB,GAAG,GAAG;AAAA,MACR;AAAA,IACF;AAEA,aAAS,iBAAiB;AACxB,UAAI,MAAM,YAAY,SAAS;AAC7B,eAAO,QAAQ;AAAA,MACjB;AAAA,IACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Loader.vue2.js","sources":["../../../../../src/components/Loader/Loader.vue"],"sourcesContent":["<template>\n <div class=\"circular-loader z-index-1 w-100 h-100 w-max-2r h-max-2r\" :class=\"{ 'circular-loader-centered': centered }\">\n <svg viewBox=\"25 25 50 50\">\n <circle class=\"circular-loader-fill\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-width=\"4\" stroke-miterlimit=\"10\" />\n <circle class=\"circular-loader-circle\" cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-width=\"4\" stroke-miterlimit=\"10\" />\n </svg>\n <div v-if=\"progress\" class=\"progress-text\">{{ progress }}</div>\n <div v-if=\"status\" class=\"uppercase fw-semi w-m-10r status-text\">{{ status }}</div>\n </div>\n</template>\n\n<script>\nexport default {\n props: {\n progress: {\n type: Number,\n default: null,\n },\n status: {\n type: String,\n default: null,\n },\n centered: {\n type: Boolean,\n default: false\n },\n },\n};\n</script>\n\n<style>\n.circular-loader-centered {\n top: calc(50% - 1rem);\n left: calc(50% - 1rem);\n}\n\n.circular-loader svg {\n animation: rotate 2s linear infinite;\n}\n\n.circular-loader-circle {\n stroke-dasharray: 1, 200;\n stroke-dashoffset: 0;\n stroke-linecap: round;\n stroke: rgb(var(--main));\n animation: dash 1.5s ease-in-out infinite;\n}\n\n.circular-loader-fill {\n stroke-linecap: round;\n stroke: rgba(var(--black),0.2);\n}\n\n.progress-text {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 0.8rem;\n color: rgb(var(--main));;\n}\n\n.status-text {\n position: absolute;\n top: 120%;\n left: calc(50% - 5rem);\n font-size: 0.8rem;\n width: 10rem !important;\n text-align: center;\n}\n\n@keyframes rotate {\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes dash {\n 0% {\n stroke-dasharray: 1, 200;\n stroke-dashoffset: 0;\n }\n 50% {\n stroke-dasharray: 89, 200;\n stroke-dashoffset: -35;\n }\n 100% {\n stroke-dasharray: 1, 200;\n stroke-dashoffset: -124;\n }\n}\n</style>"],"names":["_createElementBlock","_normalizeClass","_createElementVNode","_toDisplayString","_createCommentVNode"],"mappings":";;;AAYA,MAAK,YAAU;AAAA,EACb,OAAO;AAAA,IACL,UAAU;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA;IAEX,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA;IAEX,UAAU;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA;;AAGf;;EA3BA,KAAA;AAAA,EAMyB,OAAM;;;EAN/B,KAAA;AAAA,EAOuB,OAAM;;;sBAN3BA,mBAOM,OAAA;AAAA,IAPD,OADPC,eAAA,CACa,2DAAyD,EAAA,4BAAuC,OAAA,UAAQ,CAAA;AAAA;8BACjHC,mBAGM,OAAA,EAHD,SAAQ,iBAAa;AAAA,MACxBA,mBAAkH,UAAA;AAAA,QAA1G,OAAM;AAAA,QAAuB,IAAG;AAAA,QAAK,IAAG;AAAA,QAAK,GAAE;AAAA,QAAK,MAAK;AAAA,QAAO,gBAAa;AAAA,QAAI,qBAAkB;AAAA;MAC3GA,mBAAoH,UAAA;AAAA,QAA5G,OAAM;AAAA,QAAyB,IAAG;AAAA,QAAK,IAAG;AAAA,QAAK,GAAE;AAAA,QAAK,MAAK;AAAA,QAAO,gBAAa;AAAA,QAAI,qBAAkB;AAAA;;IAEpG,OAAA,yBAAXF,mBAA+D,OAA/D,YAA+DG,gBAAjB,OAAA,QAAQ,GAAA,CAAA,KAN1DC,mBAAA,IAAA,IAAA;AAAA,IAOe,OAAA,uBAAXJ,mBAAmF,OAAnF,YAAmFG,gBAAf,OAAA,MAAM,GAAA,CAAA,KAP9EC,mBAAA,IAAA,IAAA;AAAA;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Spoiler.vue.js","sources":["../../../../../src/components/Spoiler/Spoiler.vue"],"sourcesContent":["<template>\n <div>\n <div @click=\"toggleSpoiler\" class=\"flex-v-center flex-nowrap flex\">\n <slot name=\"header\" :isOpen=\"showSpoiler\"></slot>\n </div>\n <transition\n name=\"collapse\"\n @enter=\"onEnter\"\n @after-enter=\"onAfterEnter\"\n @leave=\"onLeave\"\n >\n <div v-show=\"showSpoiler\" class=\"spoiler\" ref=\"spoilerContent\">\n <slot name=\"content\"></slot>\n </div>\n </transition>\n </div>\n</template>\n<script setup>\nimport { ref, onMounted } from 'vue';\n\nconst props = defineProps({\n status: {\n type: Boolean,\n default: false\n }\n});\n\nconst showSpoiler = ref(false);\nconst spoilerContent = ref(null);\n\nonMounted(() => {\n if (props.status) {\n showSpoiler.value = props.status;\n }\n});\n\nconst toggleSpoiler = () => {\n showSpoiler.value = !showSpoiler.value;\n};\n\n// Анимация открытия\nconst onEnter = (el) => {\n el.style.height = '0';\n void el.offsetHeight; // force reflow\n el.style.height = el.scrollHeight + 'px';\n};\n\nconst onAfterEnter = (el) => {\n el.style.height = 'auto';\n};\n\n// Анимация закрытия\nconst onLeave = (el) => {\n el.style.height = el.scrollHeight + 'px';\n void el.offsetHeight; // force reflow\n el.style.height = '0';\n};\n\ndefineExpose({\n showSpoiler\n});\n</script>\n<style lang=\"scss\">\n.spoiler {\n overflow: hidden;\n transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;AAoBA,UAAM,QAAQ;AAOd,UAAM,cAAc,IAAI,KAAK;AAC7B,UAAM,iBAAiB,IAAI,IAAI;AAE/B,cAAU,MAAM;AACd,UAAI,MAAM,QAAQ;AAChB,oBAAY,QAAQ,MAAM;AAAA,MAC5B;AAAA,IACF,CAAC;AAED,UAAM,gBAAgB,MAAM;AAC1B,kBAAY,QAAQ,CAAC,YAAY;AAAA,IACnC;AAGA,UAAM,UAAU,CAAC,OAAO;AACtB,SAAG,MAAM,SAAS;AAClB,WAAK,GAAG;AACR,SAAG,MAAM,SAAS,GAAG,eAAe;AAAA,IACtC;AAEA,UAAM,eAAe,CAAC,OAAO;AAC3B,SAAG,MAAM,SAAS;AAAA,IACpB;AAGA,UAAM,UAAU,CAAC,OAAO;AACtB,SAAG,MAAM,SAAS,GAAG,eAAe;AACpC,WAAK,GAAG;AACR,SAAG,MAAM,SAAS;AAAA,IACpB;AAEA,aAAa;AAAA,MACX;AAAA,IACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Tab.vue.js","sources":["../../../../../src/components/Tab/Tab.vue"],"sourcesContent":["<template>\n <div class=\"flex-nowrap flex-v-center flex pos-relative\">\n <button \n v-for=\"(tab, index) in tabs\" \n :key=\"index\" \n @click=\"handleTabClick(index, tab)\" \n class=\"z-index-1 t-center cursor-pointer\"\n :style=\"isSelected(index, tab) ? 'background: rgb(var(--main)) !important' : ''\"\n :class=\"[\n isSelected(index, tab) ? 'bg-main' : '',\n replaceClasses('pd-small pd-r-medium pd-l-medium w-max pd-small radius-small', classTab)\n ]\"\n >\n {{tab.name || tab.label}}\n </button>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, watch } from 'vue'\nimport { useGlobalMixins } from '@martyrs/src/modules/core/views/mixins/mixins.js';\n\nconst { replaceClasses } = useGlobalMixins();\nconst emit = defineEmits(['update:selected', 'tab-click']);\n\nconst props = defineProps({\n tabs: Array,\n classTab: String,\n selected: [String, Number],\n modelValue: [String, Number],\n callback: Function\n})\n\nconst selectedTab = ref(0)\n\n// Handle both v-model and selected prop for backward compatibility\nconst updateSelectedIndex = () => {\n if (props.modelValue !== undefined) {\n const selectedIndex = props.tabs.findIndex(tab => tab.value === props.modelValue)\n if (selectedIndex !== -1) {\n selectedTab.value = selectedIndex\n }\n } else if (props.selected !== undefined) {\n const selectedIndex = props.tabs.findIndex(tab => tab.value === props.selected)\n if (selectedIndex !== -1) {\n selectedTab.value = selectedIndex\n }\n }\n}\n\n// Initial setup\nupdateSelectedIndex()\n\n// Watch for changes in selected or modelValue props\nwatch(() => props.selected, updateSelectedIndex)\nwatch(() => props.modelValue, updateSelectedIndex)\n\n// Check if tab is selected\nconst isSelected = (index, tab) => {\n if (props.modelValue !== undefined) {\n return tab.value === props.modelValue\n } else if (props.selected !== undefined) {\n return tab.value === props.selected\n }\n return index === selectedTab.value\n}\n\n// Handle tab click\nfunction handleTabClick(index, tab) {\n selectedTab.value = index\n \n // Emit both events for flexibility\n emit('update:selected', tab.value)\n emit('tab-click', { index, tab })\n \n // For v-model support\n if (props.modelValue !== undefined) {\n emit('update:modelValue', tab.value)\n }\n \n // Call callback if provided\n if (props.callback) props.callback(tab)\n}\n</script>\n\n<style lang=\"scss\">\n.tab-selector {\n position: absolute;\n width: 50%;\n height: 100%;\n left: 0;\n top: 0;\n z-index: 0;\n transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n</style>"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAsBA,UAAM,EAAE,eAAc,IAAK,gBAAe;AAC1C,UAAM,OAAO;AAEb,UAAM,QAAQ;AAQd,UAAM,cAAc,IAAI,CAAC;AAGzB,UAAM,sBAAsB,MAAM;AAChC,UAAI,MAAM,eAAe,QAAW;AAClC,cAAM,gBAAgB,MAAM,KAAK,UAAU,SAAO,IAAI,UAAU,MAAM,UAAU;AAChF,YAAI,kBAAkB,IAAI;AACxB,sBAAY,QAAQ;AAAA,QACtB;AAAA,MACF,WAAW,MAAM,aAAa,QAAW;AACvC,cAAM,gBAAgB,MAAM,KAAK,UAAU,SAAO,IAAI,UAAU,MAAM,QAAQ;AAC9E,YAAI,kBAAkB,IAAI;AACxB,sBAAY,QAAQ;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAGA,wBAAmB;AAGnB,UAAM,MAAM,MAAM,UAAU,mBAAmB;AAC/C,UAAM,MAAM,MAAM,YAAY,mBAAmB;AAGjD,UAAM,aAAa,CAAC,OAAO,QAAQ;AACjC,UAAI,MAAM,eAAe,QAAW;AAClC,eAAO,IAAI,UAAU,MAAM;AAAA,MAC7B,WAAW,MAAM,aAAa,QAAW;AACvC,eAAO,IAAI,UAAU,MAAM;AAAA,MAC7B;AACA,aAAO,UAAU,YAAY;AAAA,IAC/B;AAGA,aAAS,eAAe,OAAO,KAAK;AAClC,kBAAY,QAAQ;AAGpB,WAAK,mBAAmB,IAAI,KAAK;AACjC,WAAK,aAAa,EAAE,OAAO,IAAG,CAAE;AAGhC,UAAI,MAAM,eAAe,QAAW;AAClC,aAAK,qBAAqB,IAAI,KAAK;AAAA,MACrC;AAGA,UAAI,MAAM,SAAU,OAAM,SAAS,GAAG;AAAA,IACxC;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PopupAuth.vue.js","sources":["../../../../../../../../src/modules/core/views/components/blocks/PopupAuth.vue"],"sourcesContent":["<!-- @martyrs/src/modules/auth/views/components/AuthDialog.vue -->\n<template>\n <Popup \n :isPopupOpen=\"authState.visible\" \n @close-popup=\"closeAuth\"\n class=\"bg-white radius-medium pd-medium\"\n >\n <div class=\"t-center\">\n <img loading=\"lazy\" :src=\"'/logo/logo.svg'\" class=\"i-extra radius-small mn-b-medium\">\n <h3 class=\"mn-b-medium\">{{ authState.title || 'Welcome' }}</h3>\n <p class=\"mn-b-semi t-transp\">{{ authState.subtitle || 'Please sign in or create an account to continue.' }}</p>\n \n <div class=\"flex-column flex gap-thin\">\n <Button \n :submit=\"handleSignUp\" \n class=\"bg-main radius-small mn-b-small pd-thin\"\n >\n Sign Up\n </Button>\n \n <span>\n Already have an account? \n <a @click=\"handleSignIn\" class=\"t-grey cursor-pointer\">Sign in</a>\n </span>\n </div>\n </div>\n </Popup>\n</template>\n\n<script setup>\nimport { useRouter, useRoute } from 'vue-router';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport Button from '@martyrs/src/components/Button/Button.vue';\n\nconst props = defineProps({\n authState: {\n type: Object,\n required: true\n },\n closeAuth: {\n type: Function,\n required: true\n }\n});\n\nconst router = useRouter();\nconst route = useRoute();\n\nconst handleSignIn = async () => {\n const returnUrl = props.authState.returnUrl || route.fullPath;\n await router.push({ \n name: 'Sign In',\n query: { returnUrl }\n });\n props.closeAuth('signin');\n};\n\nconst handleSignUp = async () => {\n const returnUrl = props.authState.returnUrl || route.fullPath;\n await router.push({ \n name: 'Sign Up',\n query: { returnUrl }\n });\n props.closeAuth('signup');\n};\n</script>"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;AAkCA,UAAM,QAAQ;AAWd,UAAM,SAAS,UAAS;AACxB,UAAM,QAAQ,SAAQ;AAEtB,UAAM,eAAe,YAAY;AAC/B,YAAM,YAAY,MAAM,UAAU,aAAa,MAAM;AACrD,YAAM,OAAO,KAAK;AAAA,QAChB,MAAM;AAAA,QACN,OAAO,EAAE,UAAS;AAAA,MACtB,CAAG;AACD,YAAM,UAAU,QAAQ;AAAA,IAC1B;AAEA,UAAM,eAAe,YAAY;AAC/B,YAAM,YAAY,MAAM,UAAU,aAAa,MAAM;AACrD,YAAM,OAAO,KAAK;AAAA,QAChB,MAAM;AAAA,QACN,OAAO,EAAE,UAAS;AAAA,MACtB,CAAG;AACD,YAAM,UAAU,QAAQ;AAAA,IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"popup.auth.plugin.js","sources":["../../../../../../../src/modules/core/views/plugins/popup.auth.plugin.js"],"sourcesContent":["// @martyrs/src/modules/auth/views/plugins/authPlugin.js\nimport { reactive, defineComponent, h, render, defineAsyncComponent } from 'vue';\n\n// Dynamic import for better tree shaking and lazy loading\nconst PopupAuth = defineAsyncComponent(() => \n import('@martyrs/src/modules/core/views/components/blocks/PopupAuth.vue')\n);\n\n// 1) Общее состояние и API\nconst state = reactive({\n visible: false,\n title: 'Welcome',\n subtitle: 'Please sign in or create an account to continue.',\n returnUrl: '',\n resolve: null,\n reject: null\n});\n\nexport function showAuth({ \n title = 'Welcome', \n subtitle = 'Please sign in or create an account to continue.',\n returnUrl = ''\n} = {}) {\n return new Promise((res, rej) => {\n state.resolve = res;\n state.reject = rej;\n state.title = title;\n state.subtitle = subtitle;\n state.returnUrl = returnUrl;\n state.visible = true;\n });\n}\n\nexport function closeAuth(result = null) {\n state.visible = false;\n state.resolve?.(result);\n state.resolve = state.reject = null;\n}\n\nexport function cancelAuth() {\n state.visible = false;\n state.reject?.(new Error('Authentication cancelled'));\n state.resolve = state.reject = null;\n}\n\n// 2) Хост-компонент\nconst AuthDialogHost = defineComponent({\n name: 'AuthDialogHost',\n setup() {\n return () => {\n if (!state.visible) return null;\n \n return h(PopupAuth, {\n authState: state,\n closeAuth: closeAuth,\n 'onClose-popup': cancelAuth\n });\n };\n }\n});\n\n// 3) Плагин\nexport default {\n install(app) {\n // 3.1) Глобальный метод\n app.config.globalProperties.$auth = showAuth;\n app.config.globalProperties.$showAuth = showAuth;\n \n // 3.2) Контейнер в body\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n const container = document.createElement('div');\n container.id = 'auth-dialog-host';\n document.body.appendChild(container);\n \n // 3.3) Рендерим VNode в контексте основного app\n const vnode = h(AuthDialogHost);\n vnode.appContext = app._context; // <-- ключевой момент\n render(vnode, container);\n }\n }\n};"],"names":[],"mappings":";AAIA,MAAM,YAAY;AAAA,EAAqB,MACrC,OAAO,uCAAiE;AAC1E;AAGA,MAAM,QAAQ,SAAS;AAAA,EACrB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQ;AACV,CAAC;AAEM,SAAS,SAAS;AAAA,EACvB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AACd,IAAI,IAAI;AACN,SAAO,IAAI,QAAQ,CAAC,KAAK,QAAQ;AAC/B,UAAM,UAAU;AAChB,UAAM,SAAS;AACf,UAAM,QAAQ;AACd,UAAM,WAAW;AACjB,UAAM,YAAY;AAClB,UAAM,UAAU;AAAA,EAClB,CAAC;AACH;AAEO,SAAS,UAAU,SAAS,MAAM;AACvC,QAAM,UAAU;AAChB,QAAM,UAAU,MAAM;AACtB,QAAM,UAAU,MAAM,SAAS;AACjC;AAEO,SAAS,aAAa;AAC3B,QAAM,UAAU;AAChB,QAAM,SAAS,IAAI,MAAM,0BAA0B,CAAC;AACpD,QAAM,UAAU,MAAM,SAAS;AACjC;AAGA,MAAM,iBAAiB,gBAAgB;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AACN,WAAO,MAAM;AACX,UAAI,CAAC,MAAM,QAAS,QAAO;AAE3B,aAAO,EAAE,WAAW;AAAA,QAClB,WAAW;AAAA,QACX;AAAA,QACA,iBAAiB;AAAA,MACzB,CAAO;AAAA,IACH;AAAA,EACF;AACF,CAAC;AAGD,MAAA,kBAAe;AAAA,EACb,QAAQ,KAAK;AAEX,QAAI,OAAO,iBAAiB,QAAQ;AACpC,QAAI,OAAO,iBAAiB,YAAY;AAGxC,QAAI,OAAO,WAAW,eAAe,OAAO,aAAa,aAAa;AACpE,YAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,gBAAU,KAAK;AACf,eAAS,KAAK,YAAY,SAAS;AAGnC,YAAM,QAAQ,EAAE,cAAc;AAC9B,YAAM,aAAa,IAAI;AACvB,aAAO,OAAO,SAAS;AAAA,IACzB;AAAA,EACF;AACF;"}
|