adata-ui 3.1.15 → 3.1.17
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/module.json +1 -1
- package/dist/runtime/components/CurveBlock.vue +31 -20
- package/dist/runtime/components/CurveBlock.vue.d.ts +1 -1
- package/dist/runtime/components/NewFooter.vue +4 -1
- package/dist/runtime/components/feature-description/FeatureDescription.vue +105 -0
- package/dist/runtime/components/feature-description/FeatureDescription.vue.d.ts +18 -0
- package/dist/runtime/components/forms/request-demo/RequestDemo.vue +79 -58
- package/dist/runtime/components/forms/request-demo/RequestDemo.vue.d.ts +17 -20
- package/dist/runtime/components/header/AlmatyContacts.vue +3 -1
- package/dist/runtime/components/header/AstanaContacts.vue +3 -1
- package/dist/runtime/components/header/CardGallery.vue +8 -5
- package/dist/runtime/components/header/ProductMenu.vue +3 -3
- package/dist/runtime/components/photos-animation/PhotosAnimation.vue +26 -0
- package/dist/runtime/components/photos-animation/PhotosAnimation.vue.d.ts +9 -0
- package/dist/runtime/components/transitions/TransitionHeight.vue +58 -0
- package/dist/runtime/components/transitions/TransitionHeight.vue.d.ts +18 -0
- package/dist/runtime/composables/useUIValidation.d.ts +4 -0
- package/dist/runtime/composables/useUIValidation.js +14 -0
- package/dist/runtime/i18n/i18n.config.d.ts +18 -0
- package/dist/runtime/lang/en.js +6 -0
- package/dist/runtime/lang/kk.js +6 -0
- package/dist/runtime/lang/ru.d.ts +6 -0
- package/dist/runtime/lang/ru.js +7 -1
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { NuxtLinkLocale } from "#components";
|
|
3
|
-
defineProps({
|
|
4
|
-
icon: { type:
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
icon: { type: Object, required: true },
|
|
5
5
|
title: { type: String, required: true },
|
|
6
6
|
description: { type: String, required: true },
|
|
7
7
|
to: { type: String, required: false }
|
|
@@ -12,12 +12,11 @@ defineProps({
|
|
|
12
12
|
<component
|
|
13
13
|
:is="to ? NuxtLinkLocale : 'button'"
|
|
14
14
|
:to="to"
|
|
15
|
-
class="curve-block relative w-
|
|
15
|
+
class="curve-block relative w-full cursor-pointer"
|
|
16
16
|
active-class="active-item"
|
|
17
17
|
>
|
|
18
18
|
<svg
|
|
19
|
-
|
|
20
|
-
height="182"
|
|
19
|
+
class="w-full"
|
|
21
20
|
viewBox="-1 -1 308 184"
|
|
22
21
|
xmlns="http://www.w3.org/2000/svg"
|
|
23
22
|
>
|
|
@@ -60,27 +59,25 @@ defineProps({
|
|
|
60
59
|
</defs>
|
|
61
60
|
</svg>
|
|
62
61
|
|
|
63
|
-
<div class="absolute
|
|
62
|
+
<div class="absolute left-6 top-6 flex flex-col gap-4 pr-6">
|
|
64
63
|
<div class="flex items-center gap-2">
|
|
65
|
-
<div class="rounded-
|
|
64
|
+
<div class="rounded-[4px] icon-item bg-deepblue-900/5 dark:bg-gray-200/5 p-1 ">
|
|
66
65
|
<component
|
|
67
66
|
:is="icon"
|
|
68
67
|
class="size-6 shrink-0"
|
|
69
68
|
/>
|
|
70
69
|
</div>
|
|
71
|
-
<p class="text-base font-semibold">
|
|
70
|
+
<p class="text-base title font-semibold">
|
|
72
71
|
{{ title }}
|
|
73
72
|
</p>
|
|
74
73
|
</div>
|
|
75
|
-
<p class="text-sm text-gray-600 dark:text-gray-200
|
|
74
|
+
<p class="text-sm text-gray-600 dark:text-gray-200">
|
|
76
75
|
{{ description }}
|
|
77
76
|
</p>
|
|
78
77
|
</div>
|
|
79
78
|
|
|
80
79
|
<svg
|
|
81
|
-
class="absolute bottom-0 right-0"
|
|
82
|
-
width="48"
|
|
83
|
-
height="48"
|
|
80
|
+
class="absolute bottom-0 right-0 size-12 2xl:size-14"
|
|
84
81
|
viewBox="0 0 48 48"
|
|
85
82
|
xmlns="http://www.w3.org/2000/svg"
|
|
86
83
|
>
|
|
@@ -156,10 +153,12 @@ defineProps({
|
|
|
156
153
|
fill: #F4F5F6;
|
|
157
154
|
}
|
|
158
155
|
|
|
159
|
-
.active-item .
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
.active-item .title {
|
|
157
|
+
color: #0070EB;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.active-item .border-path {
|
|
161
|
+
fill: rgba(0, 112, 235, 0.1019607843);
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
.curve-block:hover .border-path,
|
|
@@ -169,6 +168,12 @@ defineProps({
|
|
|
169
168
|
fill: white;
|
|
170
169
|
}
|
|
171
170
|
|
|
171
|
+
.curve-block:hover .icon-item {
|
|
172
|
+
background-color: #E0EFFF;
|
|
173
|
+
color: #0070EB;
|
|
174
|
+
transition: all 2s ease, fill 2s ease;
|
|
175
|
+
}
|
|
176
|
+
|
|
172
177
|
.border-path {
|
|
173
178
|
stroke: url(#gradient-light);
|
|
174
179
|
}
|
|
@@ -193,10 +198,16 @@ defineProps({
|
|
|
193
198
|
.dark .animated-border {
|
|
194
199
|
fill: #26282b;
|
|
195
200
|
}
|
|
196
|
-
.dark .active-item .
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
.dark .active-item .title {
|
|
202
|
+
color: #1b98e2;
|
|
203
|
+
}
|
|
204
|
+
.dark .active-item .border-path {
|
|
205
|
+
fill: rgba(23, 146, 221, 0.38);
|
|
206
|
+
}
|
|
207
|
+
.dark .curve-block:hover .icon-item {
|
|
208
|
+
background-color: rgba(30, 88, 156, 0.6);
|
|
209
|
+
color: #1b98e2;
|
|
210
|
+
transition: all 2s ease, fill 2s ease;
|
|
200
211
|
}
|
|
201
212
|
.dark .curve-block:hover .border-path,
|
|
202
213
|
.dark .curve-block:hover .animated-border {
|
|
@@ -201,7 +201,9 @@ const contactLinks = {
|
|
|
201
201
|
</div>
|
|
202
202
|
|
|
203
203
|
<!-- contactLinks -->
|
|
204
|
-
|
|
204
|
+
<!--noindex-->
|
|
205
|
+
|
|
206
|
+
<div class="flex flex-col gap-2 items-start" data-nosnippet>
|
|
205
207
|
<nuxt-link-locale
|
|
206
208
|
class="text-sm font-semibold pb-3 pr-4 border-b border-b-[0.5px] border-white cursor-default"
|
|
207
209
|
:class="{ 'cursor-pointer': contactLinks.link }"
|
|
@@ -242,6 +244,7 @@ const contactLinks = {
|
|
|
242
244
|
</div>
|
|
243
245
|
</div>
|
|
244
246
|
</div>
|
|
247
|
+
<!--/noindex-->
|
|
245
248
|
</div>
|
|
246
249
|
|
|
247
250
|
<div class="lg:hidden flex gap-8 flex-wrap">
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { onMounted, onUnmounted } from "#imports";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
features: { type: Array, required: true }
|
|
5
|
+
});
|
|
6
|
+
const selected = defineModel({ type: Number, ...{ default: 0 } });
|
|
7
|
+
const duration = 5e3;
|
|
8
|
+
let timer = null;
|
|
9
|
+
const nextFeature = () => {
|
|
10
|
+
selected.value = (selected.value + 1) % props.features.length;
|
|
11
|
+
startTimer();
|
|
12
|
+
};
|
|
13
|
+
const startTimer = () => {
|
|
14
|
+
clearTimer();
|
|
15
|
+
timer = setTimeout(() => {
|
|
16
|
+
nextFeature();
|
|
17
|
+
}, duration);
|
|
18
|
+
};
|
|
19
|
+
const clearTimer = () => {
|
|
20
|
+
if (timer) {
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
timer = null;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function selectFeature(idx) {
|
|
26
|
+
selected.value = idx;
|
|
27
|
+
startTimer();
|
|
28
|
+
}
|
|
29
|
+
onMounted(() => startTimer());
|
|
30
|
+
onUnmounted(() => clearTimer());
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<div
|
|
35
|
+
v-for="(item, idx) in features"
|
|
36
|
+
:key="idx"
|
|
37
|
+
class="relative flex flex-col pl-3 cursor-pointer"
|
|
38
|
+
@click="selectFeature(idx)"
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
v-if="selected === idx"
|
|
42
|
+
class="absolute left-0 top-0 w-[2px] bg-blue-700 dark:bg-blue-500 z-20 h-full rounded-full"
|
|
43
|
+
:class="{ 'fill-animation': selected === idx }"
|
|
44
|
+
/>
|
|
45
|
+
|
|
46
|
+
<div
|
|
47
|
+
class="absolute left-0 top-0 w-[2px] bg-gray-500/50 z-10 h-full rounded-full"
|
|
48
|
+
/>
|
|
49
|
+
|
|
50
|
+
<div class="flex items-center gap-2 relative z-10">
|
|
51
|
+
<div
|
|
52
|
+
:class="[
|
|
53
|
+
'transition-all duration-300 ease-in-out',
|
|
54
|
+
selected === idx ? 'rounded-md bg-blue-700 dark:bg-blue-500 p-2 icon-bg' : 'size-fit'
|
|
55
|
+
]"
|
|
56
|
+
>
|
|
57
|
+
<component
|
|
58
|
+
:is="item.icon"
|
|
59
|
+
class="shrink-0 size-6 transition-colors duration-300 ease-in-out"
|
|
60
|
+
:class="selected === idx ? 'text-white dark:text-gray-900' : 'text-gray-600 dark:text-gray-200'"
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
<p
|
|
64
|
+
class="font-semibold text-base lg:text-xl transition-colors duration-300 ease-in-out"
|
|
65
|
+
:class="selected === idx ? 'dark:text-[#E3E5E8]' : 'text-gray-600 dark:text-gray-200'"
|
|
66
|
+
>
|
|
67
|
+
{{ item.title }}
|
|
68
|
+
</p>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<adt-transitions-transition-height
|
|
72
|
+
:transition="{
|
|
73
|
+
enterActiveClass: 'overflow-hidden transition-[height] duration-[1s] ease-in-out',
|
|
74
|
+
leaveActiveClass: 'overflow-hidden transition-[height] duration-[1s] ease-in-out'
|
|
75
|
+
}"
|
|
76
|
+
>
|
|
77
|
+
<div
|
|
78
|
+
v-if="selected === idx"
|
|
79
|
+
>
|
|
80
|
+
<p class="text-xs lg:text-sm pt-3">
|
|
81
|
+
{{ item.description }}
|
|
82
|
+
</p>
|
|
83
|
+
</div>
|
|
84
|
+
</adt-transitions-transition-height>
|
|
85
|
+
</div>
|
|
86
|
+
</template>
|
|
87
|
+
|
|
88
|
+
<style scoped>
|
|
89
|
+
.icon-bg {
|
|
90
|
+
box-shadow: -4px 4px 0px 0px rgba(0, 122, 255, 0.1019607843);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.fill-animation {
|
|
94
|
+
animation: borderFill 5s linear forwards;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@keyframes borderFill {
|
|
98
|
+
0% {
|
|
99
|
+
height: 0;
|
|
100
|
+
}
|
|
101
|
+
100% {
|
|
102
|
+
height: 100%;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Component } from 'vue';
|
|
2
|
+
interface FeatureInfo {
|
|
3
|
+
icon: Component;
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
}
|
|
7
|
+
type __VLS_Props = {
|
|
8
|
+
features: FeatureInfo[];
|
|
9
|
+
};
|
|
10
|
+
type __VLS_PublicProps = __VLS_Props & {
|
|
11
|
+
modelValue?: number;
|
|
12
|
+
};
|
|
13
|
+
declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
|
+
"update:modelValue": (value: number) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
16
|
+
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
17
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
|
+
export default _default;
|
|
@@ -1,67 +1,88 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
import { useUIValidation } from "~/src/runtime/composables/useUIValidation";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
title: { type: String, required: false },
|
|
6
|
+
description: { type: String, required: false }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["send"]);
|
|
7
9
|
const { t } = useI18n();
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const form = reactive({
|
|
11
|
+
sender_name: "",
|
|
12
|
+
email: "",
|
|
13
|
+
phone_number: ""
|
|
14
|
+
});
|
|
15
|
+
const submitted = ref(false);
|
|
16
|
+
const schema = z.object({
|
|
17
|
+
sender_name: z.string().nonempty(t("forms.feedback.fieldRequired")),
|
|
18
|
+
email: z.string().nonempty(t("forms.feedback.fieldRequired")).email(t("forms.feedback.emailValid")),
|
|
19
|
+
phone_number: z.string().nonempty(t("forms.feedback.fieldRequired")).min(17, t("forms.feedback.phoneMinLength", { count: 10 }))
|
|
20
|
+
});
|
|
21
|
+
const { validation, getError } = useUIValidation(schema, () => form, submitted);
|
|
22
|
+
function onSend() {
|
|
23
|
+
submitted.value = true;
|
|
24
|
+
if (validation.value) return;
|
|
25
|
+
emit("send", form);
|
|
26
|
+
submitted.value = false;
|
|
27
|
+
form.sender_name = "";
|
|
28
|
+
form.email = "";
|
|
29
|
+
form.phone_number = "";
|
|
30
|
+
}
|
|
13
31
|
</script>
|
|
14
32
|
|
|
15
33
|
<template>
|
|
16
|
-
<div class="
|
|
17
|
-
<div class="flex flex-col gap-
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<div class="flex flex-col gap-2 sm:w-1/2 sm:gap-4">
|
|
30
|
-
<input-standard
|
|
31
|
-
v-model="fullName"
|
|
32
|
-
color-classes="bg-gray-50 dark:bg-gray-800"
|
|
33
|
-
:label="t('forms.demo.n')"
|
|
34
|
-
required
|
|
35
|
-
size="md"
|
|
36
|
-
:disabled="isLoading"
|
|
37
|
-
/>
|
|
38
|
-
<input-standard
|
|
39
|
-
v-model="phone"
|
|
40
|
-
v-maska
|
|
41
|
-
color-classes="bg-gray-50 dark:bg-gray-800"
|
|
42
|
-
type="tel"
|
|
43
|
-
:label="t('forms.demo.p')"
|
|
44
|
-
data-maska="8 (###) ###-##-##"
|
|
45
|
-
required
|
|
46
|
-
size="md"
|
|
47
|
-
:disabled="isLoading"
|
|
48
|
-
/>
|
|
34
|
+
<div class="rounded-[20px] bg-blue-700 dark:bg-[#1B98E2] p-4 dark:bg-blue-500 lg:p-8">
|
|
35
|
+
<div class="flex w-full flex-col gap-4 lg:flex-row lg:justify-between">
|
|
36
|
+
<div class="flex flex-col gap-4 text-white dark:text-gray-900 lg:max-w-[50%] lg:gap-6">
|
|
37
|
+
<slot name="title">
|
|
38
|
+
<p class="md:text-[32px] text-[24px] font-bold">
|
|
39
|
+
{{ title || t("forms.request_demo.title") }}
|
|
40
|
+
</p>
|
|
41
|
+
</slot>
|
|
42
|
+
<slot name="description">
|
|
43
|
+
<p class="text-base whitespace-pre-line">
|
|
44
|
+
{{ description || t("forms.request_demo.info") }}
|
|
45
|
+
</p>
|
|
46
|
+
</slot>
|
|
49
47
|
</div>
|
|
50
|
-
<div class="
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
<div class="rounded-[20px] bg-white p-6 dark:bg-gray-900 lg:w-[456px]">
|
|
49
|
+
<div class="flex flex-col gap-4">
|
|
50
|
+
<slot name="inputs">
|
|
51
|
+
<div class="flex flex-col gap-4">
|
|
52
|
+
<adt-forms-input-standard
|
|
53
|
+
v-model="form.sender_name"
|
|
54
|
+
required
|
|
55
|
+
:label="t('forms.demo.n')"
|
|
56
|
+
:error="getError('sender_name')"
|
|
57
|
+
/>
|
|
58
|
+
<adt-forms-input-standard
|
|
59
|
+
v-model="form.email"
|
|
60
|
+
required
|
|
61
|
+
:label="t('forms.demo.e')"
|
|
62
|
+
:error="getError('email')"
|
|
63
|
+
type="email"
|
|
64
|
+
/>
|
|
65
|
+
<adt-forms-input-standard
|
|
66
|
+
v-model="form.phone_number"
|
|
67
|
+
v-maska
|
|
68
|
+
required
|
|
69
|
+
data-maska="8 (###) ###-##-##"
|
|
70
|
+
:label="t('forms.demo.p')"
|
|
71
|
+
:error="getError('phone_number')"
|
|
72
|
+
type="tel"
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
</slot>
|
|
76
|
+
<div>
|
|
77
|
+
<a-button
|
|
78
|
+
block
|
|
79
|
+
@click="onSend"
|
|
80
|
+
>
|
|
81
|
+
{{ t("forms.request_demo.send") }}
|
|
82
|
+
</a-button>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
61
85
|
</div>
|
|
62
|
-
</
|
|
63
|
-
<a-button class="w-full self-end sm:w-[215px] font-semibold" :disabled="isLoading">
|
|
64
|
-
{{ t("forms.demo.b") }}
|
|
65
|
-
</a-button>
|
|
86
|
+
</div>
|
|
66
87
|
</div>
|
|
67
88
|
</template>
|
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
title?: string;
|
|
3
|
+
description?: string;
|
|
4
4
|
};
|
|
5
|
-
declare
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {};
|
|
6
|
+
type __VLS_Slots = {} & {
|
|
7
|
+
title?: (props: typeof __VLS_1) => any;
|
|
8
8
|
} & {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
onOnSend?: ((form: {
|
|
16
|
-
sender_name: string;
|
|
17
|
-
phone_number: string;
|
|
18
|
-
message: string;
|
|
19
|
-
}) => any) | undefined;
|
|
20
|
-
"onUpdate:loading"?: ((value: boolean) => any) | undefined;
|
|
21
|
-
"onUpdate:modal"?: ((value: boolean) => any) | undefined;
|
|
22
|
-
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
description?: (props: typeof __VLS_3) => any;
|
|
10
|
+
} & {
|
|
11
|
+
inputs?: (props: typeof __VLS_5) => any;
|
|
12
|
+
};
|
|
13
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
23
15
|
export default _default;
|
|
16
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
17
|
+
new (): {
|
|
18
|
+
$slots: S;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -43,7 +43,8 @@ const newContacts = computed(() => contacts.value.map((item) => ({
|
|
|
43
43
|
</script>
|
|
44
44
|
|
|
45
45
|
<template>
|
|
46
|
-
|
|
46
|
+
<!--noindex-->
|
|
47
|
+
<div class="h-[272px]" data-nosnippet>
|
|
47
48
|
<h2 class="heading-02 mb-4">
|
|
48
49
|
{{ t("header.contacts.almaty.title") }}
|
|
49
50
|
</h2>
|
|
@@ -117,4 +118,5 @@ const newContacts = computed(() => contacts.value.map((item) => ({
|
|
|
117
118
|
</div>
|
|
118
119
|
</div>
|
|
119
120
|
</div>
|
|
121
|
+
<!--/noindex-->
|
|
120
122
|
</template>
|
|
@@ -33,7 +33,8 @@ const AstanaItems = [
|
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<template>
|
|
36
|
-
|
|
36
|
+
<!--noindex-->
|
|
37
|
+
<div class="h-[272px]" data-nosnippet>
|
|
37
38
|
<h2 class="heading-02 mb-4">
|
|
38
39
|
{{ t("header.contacts.astana.title") }}
|
|
39
40
|
</h2>
|
|
@@ -62,4 +63,5 @@ const AstanaItems = [
|
|
|
62
63
|
</div>
|
|
63
64
|
</div>
|
|
64
65
|
</div>
|
|
66
|
+
<!--/noindex-->
|
|
65
67
|
</template>
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
2
|
+
import { PAGES } from "../../shared/constants/pages";
|
|
3
|
+
import { computed, onMounted, onUnmounted, ref, useAppConfig, useI18n } from "#imports";
|
|
3
4
|
import ArrowSideUp from "#icons/arrow/arrow-side-up.vue";
|
|
4
5
|
import { IArrowCircleDown, IGlobe, IId } from "#components";
|
|
5
6
|
const { t } = useI18n();
|
|
7
|
+
const appConfig = useAppConfig();
|
|
8
|
+
const mode = appConfig.adataUI.mode;
|
|
6
9
|
const items = computed(() => {
|
|
7
10
|
return [
|
|
8
11
|
{
|
|
9
12
|
title: "header.products.galleryCards.unload.title",
|
|
10
13
|
subtitle: "header.products.galleryCards.unload.subtitle",
|
|
11
|
-
to:
|
|
14
|
+
to: `https://pk.${mode}.kz` + PAGES.pk.unload,
|
|
12
15
|
image: "/header/unload.webp",
|
|
13
16
|
icon: IArrowCircleDown
|
|
14
17
|
},
|
|
15
18
|
{
|
|
16
19
|
title: "header.products.galleryCards.compliance.title",
|
|
17
20
|
subtitle: "header.products.galleryCards.compliance.subtitle",
|
|
18
|
-
to:
|
|
21
|
+
to: `https://ac.${mode}.kz`,
|
|
19
22
|
image: "/header/compliance.webp",
|
|
20
23
|
icon: IId
|
|
21
24
|
},
|
|
22
25
|
{
|
|
23
26
|
title: "header.products.galleryCards.ved.title",
|
|
24
27
|
subtitle: "header.products.galleryCards.ved.subtitle",
|
|
25
|
-
to:
|
|
28
|
+
to: `https://tnved.${mode}.kz`,
|
|
26
29
|
image: "/header/ved.webp",
|
|
27
30
|
icon: IGlobe
|
|
28
31
|
}
|
|
@@ -103,7 +106,7 @@ onUnmounted(() => clearTimer());
|
|
|
103
106
|
<img
|
|
104
107
|
:src="items[currentIndex].image"
|
|
105
108
|
class="size-full object-cover rounded-2xl"
|
|
106
|
-
|
|
109
|
+
>
|
|
107
110
|
<nuxt-link :to="items[currentIndex].to">
|
|
108
111
|
<div class="absolute bottom-0 rounded-2xl w-full bg-blue-700/80 dark:bg-blue-500/80 px-4 pt-4 pb-12 shadow-[0_-2px_4px_0_rgba(0,0,0,0.25)] backdrop-blur-md flex flex-col gap-6">
|
|
109
112
|
<div class="flex flex-col gap-2">
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { PAGES } from "../../shared/constants/pages";
|
|
3
3
|
import NavList from "./NavList.vue";
|
|
4
4
|
import CardGallery from "./CardGallery.vue";
|
|
5
|
-
import { useI18n, useAppConfig, useRequestURL } from "#imports";
|
|
5
|
+
import { useI18n, useAppConfig, useRequestURL, computed } from "#imports";
|
|
6
6
|
import IUsersThree from "#icons/users/users-three.vue";
|
|
7
7
|
import ISearch from "#icons/search.vue";
|
|
8
8
|
import IArrowCircleDown from "#icons/arrow/arrow-circle-down.vue";
|
|
@@ -42,7 +42,7 @@ const appConfig = useAppConfig();
|
|
|
42
42
|
const mode = appConfig.adataUI.mode;
|
|
43
43
|
const pageUrl = useRequestURL();
|
|
44
44
|
defineEmits(["outerClick", "mouseOver"]);
|
|
45
|
-
const filteredItems = [
|
|
45
|
+
const filteredItems = computed(() => [
|
|
46
46
|
{
|
|
47
47
|
key: "edo",
|
|
48
48
|
is_new: true,
|
|
@@ -274,7 +274,7 @@ const filteredItems = [
|
|
|
274
274
|
}
|
|
275
275
|
]
|
|
276
276
|
}
|
|
277
|
-
];
|
|
277
|
+
]);
|
|
278
278
|
function isCurrentModule(currentModule) {
|
|
279
279
|
if (currentModule === "fines") return "avto";
|
|
280
280
|
if (currentModule === "analytics") return "analytics-new";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
photos: { type: Array, required: true }
|
|
4
|
+
});
|
|
5
|
+
const getAnimationClass = (index) => {
|
|
6
|
+
if (props.photos.length === 1) return "fade-in";
|
|
7
|
+
const directions = ["from-top", "from-right", "from-bottom", "from-left"];
|
|
8
|
+
return directions[index % 4];
|
|
9
|
+
};
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="relative size-full">
|
|
14
|
+
<img
|
|
15
|
+
v-for="(photo, index) in photos"
|
|
16
|
+
:key="index"
|
|
17
|
+
:src="photo.src"
|
|
18
|
+
:alt="photo.src"
|
|
19
|
+
:class="['photo', getAnimationClass(index), photo.classes]"
|
|
20
|
+
>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<style scoped>
|
|
25
|
+
.photo{animation:fadeSlide 1s forwards;opacity:0;position:absolute;transform:translate(0)}.fade-in{animation:fadeOnly 1s forwards}.from-top{animation-name:slideFromTop}.from-right{animation-name:slideFromRight}.from-bottom{animation-name:slideFromBottom}.from-left{animation-name:slideFromLeft}@keyframes fadeOnly{0%{opacity:0}to{opacity:1}}@keyframes slideFromTop{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}@keyframes slideFromRight{0%{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes slideFromBottom{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes slideFromLeft{0%{opacity:0;transform:translateX(-20px)}to{opacity:1;transform:translateX(0)}}.photo{animation-duration:1s;animation-fill-mode:forwards}
|
|
26
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Photo {
|
|
2
|
+
src: string;
|
|
3
|
+
classes: string;
|
|
4
|
+
}
|
|
5
|
+
type __VLS_Props = {
|
|
6
|
+
photos: Photo[];
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
import { computed } from "#imports";
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
transition: { type: Object, required: false }
|
|
6
|
+
});
|
|
7
|
+
const ui = {
|
|
8
|
+
transition: {
|
|
9
|
+
enterActiveClass: "overflow-hidden transition-[height] duration-200 ease-out",
|
|
10
|
+
leaveActiveClass: "overflow-hidden transition-[height] duration-200 ease-out"
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const mergedUi = computed(() => ({
|
|
14
|
+
transition: {
|
|
15
|
+
enterActiveClass: twMerge(
|
|
16
|
+
ui.transition.enterActiveClass,
|
|
17
|
+
props.transition?.enterActiveClass
|
|
18
|
+
),
|
|
19
|
+
leaveActiveClass: twMerge(
|
|
20
|
+
ui.transition.leaveActiveClass,
|
|
21
|
+
props.transition?.leaveActiveClass
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
}));
|
|
25
|
+
function onEnter(_el, done) {
|
|
26
|
+
const el = _el;
|
|
27
|
+
el.style.height = "0";
|
|
28
|
+
el.offsetHeight;
|
|
29
|
+
el.style.height = el.scrollHeight + "px";
|
|
30
|
+
el.addEventListener("transitionend", done, { once: true });
|
|
31
|
+
}
|
|
32
|
+
function onBeforeLeave(_el) {
|
|
33
|
+
const el = _el;
|
|
34
|
+
el.style.height = el.scrollHeight + "px";
|
|
35
|
+
el.offsetHeight;
|
|
36
|
+
}
|
|
37
|
+
function onAfterEnter(_el) {
|
|
38
|
+
const el = _el;
|
|
39
|
+
el.style.height = "auto";
|
|
40
|
+
}
|
|
41
|
+
function onLeave(_el, done) {
|
|
42
|
+
const el = _el;
|
|
43
|
+
el.style.height = "0";
|
|
44
|
+
el.addEventListener("transitionend", done, { once: true });
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<Transition
|
|
50
|
+
v-bind="mergedUi.transition"
|
|
51
|
+
@enter="onEnter"
|
|
52
|
+
@after-enter="onAfterEnter"
|
|
53
|
+
@before-leave="onBeforeLeave"
|
|
54
|
+
@leave="onLeave"
|
|
55
|
+
>
|
|
56
|
+
<slot />
|
|
57
|
+
</Transition>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
transition?: {
|
|
3
|
+
enterActiveClass?: string;
|
|
4
|
+
leaveActiveClass?: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_12: {};
|
|
8
|
+
type __VLS_Slots = {} & {
|
|
9
|
+
default?: (props: typeof __VLS_12) => any;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
13
|
+
export default _default;
|
|
14
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
15
|
+
new (): {
|
|
16
|
+
$slots: S;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function useUIValidation(schema, data, submitted) {
|
|
2
|
+
const validation = computed(() => {
|
|
3
|
+
if (!submitted.value) return null;
|
|
4
|
+
const result = schema.safeParse(data());
|
|
5
|
+
return result.success ? null : result.error;
|
|
6
|
+
});
|
|
7
|
+
function getError(path) {
|
|
8
|
+
return validation.value?.issues.find((issue) => issue.path[0] === path)?.message;
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
validation,
|
|
12
|
+
getError
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -382,6 +382,12 @@ declare const _default: {
|
|
|
382
382
|
modalTitle: string;
|
|
383
383
|
modalSubtitle: string;
|
|
384
384
|
};
|
|
385
|
+
request_demo: {
|
|
386
|
+
title: string;
|
|
387
|
+
info: string;
|
|
388
|
+
agreement: string;
|
|
389
|
+
send: string;
|
|
390
|
+
};
|
|
385
391
|
demo: {
|
|
386
392
|
t: string;
|
|
387
393
|
st: string;
|
|
@@ -946,6 +952,12 @@ declare const _default: {
|
|
|
946
952
|
modalTitle: string;
|
|
947
953
|
modalSubtitle: string;
|
|
948
954
|
};
|
|
955
|
+
request_demo: {
|
|
956
|
+
title: string;
|
|
957
|
+
info: string;
|
|
958
|
+
agreement: string;
|
|
959
|
+
send: string;
|
|
960
|
+
};
|
|
949
961
|
demo: {
|
|
950
962
|
t: string;
|
|
951
963
|
st: string;
|
|
@@ -1510,6 +1522,12 @@ declare const _default: {
|
|
|
1510
1522
|
modalTitle: string;
|
|
1511
1523
|
modalSubtitle: string;
|
|
1512
1524
|
};
|
|
1525
|
+
request_demo: {
|
|
1526
|
+
title: string;
|
|
1527
|
+
info: string;
|
|
1528
|
+
agreement: string;
|
|
1529
|
+
send: string;
|
|
1530
|
+
};
|
|
1513
1531
|
demo: {
|
|
1514
1532
|
t: string;
|
|
1515
1533
|
st: string;
|
package/dist/runtime/lang/en.js
CHANGED
|
@@ -376,6 +376,12 @@ const EnLocale = {
|
|
|
376
376
|
modalTitle: "Request Accepted",
|
|
377
377
|
modalSubtitle: "Thank you for your feedback!"
|
|
378
378
|
},
|
|
379
|
+
request_demo: {
|
|
380
|
+
title: "Try all the features of the service for free",
|
|
381
|
+
info: "Check the functionality and quality of the data in real conditions. Demo access will allow you to test all the key features of the service.\nFill out the form to submit a connection request",
|
|
382
|
+
agreement: "By filling out the form, you agree to the processing of personal data and receiving informational messages",
|
|
383
|
+
send: "Submit Request"
|
|
384
|
+
},
|
|
379
385
|
demo: {
|
|
380
386
|
t: "Request Demo Access",
|
|
381
387
|
st: "Fill out the form to request demo access",
|
package/dist/runtime/lang/kk.js
CHANGED
|
@@ -376,6 +376,12 @@ const KkLocale = {
|
|
|
376
376
|
modalTitle: "\u04E8\u0442\u0456\u043D\u0456\u043C \u049B\u0430\u0431\u044B\u043B\u0434\u0430\u043D\u0434\u044B",
|
|
377
377
|
modalSubtitle: "\u049A\u0430\u0442\u044B\u0441\u049B\u0430\u043D\u044B\u04A3\u044B\u0437 \u04AF\u0448\u0456\u043D \u0440\u0430\u0445\u043C\u0435\u0442!"
|
|
378
378
|
},
|
|
379
|
+
request_demo: {
|
|
380
|
+
title: "\u049A\u044B\u0437\u043C\u0435\u0442\u0442\u0456\u04A3 \u0431\u0430\u0440\u043B\u044B\u049B \u043C\u04AF\u043C\u043A\u0456\u043D\u0434\u0456\u043A\u0442\u0435\u0440\u0456\u043D \u0442\u0435\u0433\u0456\u043D \u049B\u043E\u043B\u0434\u0430\u043D\u044B\u043F \u043A\u04E9\u0440\u0456\u04A3\u0456\u0437",
|
|
381
|
+
info: "\u0414\u0435\u0440\u0435\u043A\u0442\u0435\u0440\u0434\u0456\u04A3 \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u0434\u044B\u0493\u044B\u043D \u0436\u04D9\u043D\u0435 \u0441\u0430\u043F\u0430\u0441\u044B\u043D \u043D\u0430\u049B\u0442\u044B \u0436\u0430\u0493\u0434\u0430\u0439\u043B\u0430\u0440\u0434\u0430 \u0442\u0435\u043A\u0441\u0435\u0440\u0456\u04A3\u0456\u0437. \u0414\u0435\u043C\u043E-\u049B\u043E\u043B\u0436\u0435\u0442\u0456\u043C\u0434\u0456\u043B\u0456\u043A \u049B\u044B\u0437\u043C\u0435\u0442\u0442\u0456\u04A3 \u0431\u0430\u0440\u043B\u044B\u049B \u043D\u0435\u0433\u0456\u0437\u0433\u0456 \u043C\u04AF\u043C\u043A\u0456\u043D\u0434\u0456\u043A\u0442\u0435\u0440\u0456\u043D \u0441\u044B\u043D\u0430\u043F \u043A\u04E9\u0440\u0443\u0433\u0435 \u043C\u04AF\u043C\u043A\u0456\u043D\u0434\u0456\u043A \u0431\u0435\u0440\u0435\u0434\u0456.\n\u049A\u043E\u0441\u044B\u043B\u0443\u0493\u0430 \u04E9\u0442\u0456\u043D\u0456\u043C \u0431\u0435\u0440\u0443 \u04AF\u0448\u0456\u043D \u0444\u043E\u0440\u043C\u0430\u043D\u044B \u0442\u043E\u043B\u0442\u044B\u0440\u044B\u04A3\u044B\u0437",
|
|
382
|
+
agreement: "\u041F\u0456\u0448\u0456\u043D\u0434\u0456 \u0442\u043E\u043B\u0442\u044B\u0440\u0430 \u043E\u0442\u044B\u0440\u044B\u043F, \u0441\u0456\u0437 \u0436\u0435\u043A\u0435 \u0434\u0435\u0440\u0435\u043A\u0442\u0435\u0440\u0434\u0456 \u04E9\u04A3\u0434\u0435\u0443\u0433\u0435 \u0436\u04D9\u043D\u0435 \u0430\u049B\u043F\u0430\u0440\u0430\u0442\u0442\u044B\u049B \u0445\u0430\u0431\u0430\u0440\u043B\u0430\u043C\u0430\u043B\u0430\u0440\u0434\u044B \u0430\u043B\u0443\u0493\u0430 \u043A\u0435\u043B\u0456\u0441\u0456\u043C \u0431\u0435\u0440\u0435\u0441\u0456\u0437",
|
|
383
|
+
send: "\u04E8\u0442\u0456\u043D\u0456\u043C\u0434\u0456 \u0436\u0456\u0431\u0435\u0440\u0443"
|
|
384
|
+
},
|
|
379
385
|
demo: {
|
|
380
386
|
t: "\u0414\u0435\u043C\u043E \u049B\u043E\u043B\u0436\u0435\u0442\u0456\u043C\u0434\u0456\u043B\u0456\u043A\u0442\u0456 \u0441\u04B1\u0440\u0430\u0443",
|
|
381
387
|
st: "\u0414\u0435\u043C\u043E \u049B\u043E\u043B\u0436\u0435\u0442\u0456\u043C\u0434\u0456\u043B\u0456\u043A\u0442\u0456 \u0441\u04B1\u0440\u0430\u0443 \u04AF\u0448\u0456\u043D \u0444\u043E\u0440\u043C\u0430\u043D\u044B \u0442\u043E\u043B\u0442\u044B\u0440\u044B\u04A3\u044B\u0437",
|
package/dist/runtime/lang/ru.js
CHANGED
|
@@ -275,7 +275,7 @@ const RuLocale = {
|
|
|
275
275
|
},
|
|
276
276
|
toContacts: "\u041D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u041A\u043E\u043D\u0442\u0430\u043A\u0442\u044B"
|
|
277
277
|
},
|
|
278
|
-
login: "\u0412\
|
|
278
|
+
login: "\u0412\u043E\u0439\u0442\u0438",
|
|
279
279
|
oldVersion: "\u0421\u0442\u0430\u0440\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0441\u0430\u0439\u0442\u0430",
|
|
280
280
|
notifications: {
|
|
281
281
|
title: "\u0423\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F",
|
|
@@ -370,6 +370,12 @@ const RuLocale = {
|
|
|
370
370
|
modalTitle: "\u0417\u0430\u044F\u0432\u043A\u0430 \u043F\u0440\u0438\u043D\u044F\u0442\u0430",
|
|
371
371
|
modalSubtitle: "\u0421\u043F\u0430\u0441\u0438\u0431\u043E \u0437\u0430 \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u0435!"
|
|
372
372
|
},
|
|
373
|
+
request_demo: {
|
|
374
|
+
title: "\u041F\u043E\u043F\u0440\u043E\u0431\u0443\u0439\u0442\u0435 \u0432\u0441\u0435 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0431\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u043E",
|
|
375
|
+
info: "\u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B \u0438 \u043A\u0430\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u0430\u043D\u043D\u044B\u0445 \u0432 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0445 \u0443\u0441\u043B\u043E\u0432\u0438\u044F\u0445. \u0414\u0435\u043C\u043E-\u0434\u043E\u0441\u0442\u0443\u043F \u043F\u043E\u0437\u0432\u043E\u043B\u0438\u0442 \u043F\u0440\u043E\u0442\u0435\u0441\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u0441\u0435 \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430.\n\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0444\u043E\u0440\u043C\u0443, \u0447\u0442\u043E\u0431\u044B \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443 \u043D\u0430 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435",
|
|
376
|
+
agreement: "\u0417\u0430\u043F\u043E\u043B\u043D\u044F\u044F \u0444\u043E\u0440\u043C\u0443, \u0432\u044B \u0441\u043E\u0433\u043B\u0430\u0448\u0430\u0435\u0442\u0435\u0441\u044C \u043D\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443 \u043F\u0435\u0440\u0441\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438 \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439",
|
|
377
|
+
send: "\u041E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443"
|
|
378
|
+
},
|
|
373
379
|
demo: {
|
|
374
380
|
t: "\u0417\u0430\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u0434\u0435\u043C\u043E-\u0434\u043E\u0441\u0442\u0443\u043F",
|
|
375
381
|
st: "\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0444\u043E\u0440\u043C\u0443, \u0447\u0442\u043E\u0431\u044B \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443 \u043D\u0430 \u0434\u0435\u043C\u043E-\u0434\u043E\u0441\u0442\u0443\u043F",
|