vgapp 0.7.9 → 0.8.1
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/CHANGELOG.md +9 -0
- package/app/langs/en/buttons.json +16 -0
- package/app/langs/en/messages.json +32 -0
- package/app/langs/en/titles.json +6 -0
- package/app/langs/ru/buttons.json +16 -0
- package/app/langs/ru/messages.json +32 -0
- package/app/langs/ru/titles.json +6 -0
- package/app/modules/base-module.js +12 -1
- package/app/modules/module-fn.js +20 -9
- package/app/modules/vgalert/js/vgalert.js +12 -6
- package/app/modules/vgalert/readme.md +1 -1
- package/app/modules/vgcollapse/readme.md +1 -1
- package/app/modules/vgdropdown/js/vgdropdown.js +140 -38
- package/app/modules/vgdropdown/readme.md +225 -0
- package/app/modules/vgfiles/js/base.js +499 -0
- package/app/modules/vgfiles/js/droppable.js +159 -0
- package/app/modules/vgfiles/js/loader.js +389 -0
- package/app/modules/vgfiles/js/render.js +83 -0
- package/app/modules/vgfiles/js/sortable.js +155 -0
- package/app/modules/vgfiles/js/vgfiles.js +796 -280
- package/app/modules/vgfiles/readme.md +193 -0
- package/app/modules/vgfiles/scss/_animations.scss +18 -0
- package/app/modules/vgfiles/scss/_mixins.scss +73 -0
- package/app/modules/vgfiles/scss/_variables.scss +103 -26
- package/app/modules/vgfiles/scss/vgfiles.scss +573 -60
- package/app/modules/vgformsender/js/vgformsender.js +5 -1
- package/app/modules/vgformsender/readme.md +1 -1
- package/app/modules/vglawcookie/js/vglawcookie.js +96 -62
- package/app/modules/vglawcookie/readme.md +102 -0
- package/app/modules/vgloadmore/js/vgloadmore.js +212 -112
- package/app/modules/vgloadmore/readme.md +145 -0
- package/app/modules/vgsidebar/js/vgsidebar.js +6 -4
- package/app/utils/js/components/ajax.js +172 -122
- package/app/utils/js/components/animation.js +124 -39
- package/app/utils/js/components/backdrop.js +54 -31
- package/app/utils/js/components/lang.js +69 -88
- package/app/utils/js/components/params.js +34 -31
- package/app/utils/js/components/scrollbar.js +118 -67
- package/app/utils/js/components/templater.js +14 -4
- package/app/utils/js/dom/cookie.js +107 -64
- package/app/utils/js/dom/data.js +68 -20
- package/app/utils/js/dom/event.js +272 -239
- package/app/utils/js/dom/manipulator.js +135 -62
- package/app/utils/js/dom/selectors.js +134 -59
- package/app/utils/js/functions.js +183 -349
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/package.json +1 -1
- package/app/utils/js/components/overflow.js +0 -28
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# VGFiles — Модуль загрузки и управления файлами
|
|
2
|
+
|
|
3
|
+
`VGFiles` — это расширяемый и гибкий JavaScript-модуль для управления файлами на веб-странице, поддерживающий как локальную работу с файлами, так и асинхронную загрузку через AJAX. Модуль интегрируется с DOM-элементами, предоставляет визуальный интерфейс, поддерживает драг-н-дроп, валидацию, сортировку, отслеживание статусов и обработку событий.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🔧 Возможности
|
|
8
|
+
|
|
9
|
+
### ✅ Основные функции
|
|
10
|
+
- **Добавление файлов** через `<input type="file">` или **drag & drop**.
|
|
11
|
+
- **Просмотр списков файлов** с превью (если тип — изображение).
|
|
12
|
+
- **Удаление отдельных файлов** и **очистка всего списка**.
|
|
13
|
+
- **Интеграция с сервером** через AJAX-запросы (загрузка, удаление, сортировка).
|
|
14
|
+
- **Автоматическая валидация** по типу, количеству, размеру файлов.
|
|
15
|
+
- **Многоязычная поддержка** (настраиваемые кнопки и сообщения).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Установка и инициализация
|
|
20
|
+
|
|
21
|
+
Модуль автоматически инициализируется на элементах с классом `.vg-files` при загрузке DOM:
|
|
22
|
+
|
|
23
|
+
Или вручную:
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
const files = new VGFiles(document.querySelector('.vg-files'), {
|
|
27
|
+
ajax: true,
|
|
28
|
+
uploads: {
|
|
29
|
+
route: '/api/upload',
|
|
30
|
+
mode: 'sequential'
|
|
31
|
+
},
|
|
32
|
+
limits: {
|
|
33
|
+
count: 10,
|
|
34
|
+
sizes: 5, // MB
|
|
35
|
+
total: 50
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## ⚙️ Параметры конфигурации
|
|
43
|
+
|
|
44
|
+
| Параметр | Тип | По умолчанию | Описание |
|
|
45
|
+
|--------|------|-------------|---------|
|
|
46
|
+
| `init` | `boolean` | `true` | Автоматическая инициализация |
|
|
47
|
+
| `allowed` | `boolean` | `false` | Разрешить дроп файлов |
|
|
48
|
+
| `lang` | `string` | `'ru'` | Язык интерфейса (поддерживается через `lang_buttons`, `lang_messages`) |
|
|
49
|
+
| `limits.count` | `number` | `0` | Макс. количество файлов (0 — без ограничений) |
|
|
50
|
+
| `limits.sizes` | `number` | `10` | Макс. размер одного файла (в МБ) |
|
|
51
|
+
| `limits.total` | `number` | `0` | Общий лимит размера (в МБ, 0 — без ограничений) |
|
|
52
|
+
| `image` | `boolean` | `false` | Отображать превью изображений |
|
|
53
|
+
| `detach` | `boolean` | `true` | Откреплять файлы после загрузки |
|
|
54
|
+
| `info` | `boolean` | `true` | Показывать кнопку удаления |
|
|
55
|
+
| `types` | `array` | `[]` | Разрешённые MIME-типы (например, `['image/png', 'application/pdf']`) |
|
|
56
|
+
| `ajax` | `boolean` | `false` | Использовать AJAX-загрузку |
|
|
57
|
+
| `prepend` | `boolean` | `true` | Добавлять новые файлы в начало списка |
|
|
58
|
+
| `uploads.route` | `string` | `''` | URL для загрузки файлов |
|
|
59
|
+
| `uploads.mode` | `'sequential' \| 'parallel'` | `'sequential'` | Режим отправки файлов |
|
|
60
|
+
| `uploads.maxParallel` | `number` | `3` | Макс. файлов при параллельной загрузке |
|
|
61
|
+
| `uploads.maxConcurrent` | `number` | `1` | Макс. одновременных запросов |
|
|
62
|
+
| `uploads.retryAttempts` | `number` | `1` | Кол-во попыток повтора при ошибке |
|
|
63
|
+
| `uploads.retryDelay` | `number` | `1000` | Задержка между попытками (мс) |
|
|
64
|
+
| `removes.single.route` | `string` | `''` | URL для удаления одного файла |
|
|
65
|
+
| `removes.all.route` | `string` | `''` | URL для удаления всех файлов |
|
|
66
|
+
| `removes.single.alert` | `boolean` | `true` | Показывать подтверждение при удалении |
|
|
67
|
+
| `removes.single.toast` | `boolean` | `true` | Показывать уведомление после удаления |
|
|
68
|
+
| `sortable.enabled` | `boolean` | `false` | Включить сортировку |
|
|
69
|
+
| `sortable.route` | `string` | `''` | URL для сохранения порядка файлов |
|
|
70
|
+
| `callbacks` | `object` | `null` | Колбэки на события (см. ниже) |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 📢 События и колбэки
|
|
75
|
+
|
|
76
|
+
Модуль поддерживает как DOM-события, так и JS-колбэки:
|
|
77
|
+
|
|
78
|
+
### DOM-события
|
|
79
|
+
- `vg.files.change` — изменение списка файлов
|
|
80
|
+
- `vg.files.upload.allComplete` — все файлы загружены
|
|
81
|
+
- `vg.files.remove` — файл удалён
|
|
82
|
+
|
|
83
|
+
### Колбэки (`callbacks`)
|
|
84
|
+
| Колбэк | Параметры | Описание |
|
|
85
|
+
|-------|----------|--------|
|
|
86
|
+
| `onInit` | `(data)` | Инициализация завершена |
|
|
87
|
+
| `onChange` | `{ files, input }` | Изменён список файлов |
|
|
88
|
+
| `onUploadStart` | `{ files, total }` | Началась загрузка |
|
|
89
|
+
| `onUploadProgress` | `{ file, progress, bytesSent, totalBytes }` | Прогресс загрузки |
|
|
90
|
+
| `onUploadComplete` | `{ file, response, status, id }` | Файл успешно загружен |
|
|
91
|
+
| `onUploadError` | `{ file }` | Ошибка загрузки |
|
|
92
|
+
| `onUploadAllComplete` | `{ uploaded, failed, total }` | Все файлы загружены |
|
|
93
|
+
| `onRemoveFile` | `{ button, name, size, id, remaining }` | Удалён файл |
|
|
94
|
+
| `onClear` | `{}` | Очищен весь список |
|
|
95
|
+
| `onReload` | `{ button, file }` | Повторная попытка загрузки |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 📊 Статусы файлов
|
|
100
|
+
|
|
101
|
+
Модуль отслеживает статусы в реальном времени:
|
|
102
|
+
- **`pending`** — ожидает загрузки
|
|
103
|
+
- **`loading`** — идёт загрузка
|
|
104
|
+
- **`completed`** — успешно загружен
|
|
105
|
+
- **`failing`** — ошибка загрузки
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 🔁 Внешние (уже загруженные) файлы
|
|
110
|
+
|
|
111
|
+
Модуль может отображать уже загруженные файлы, переданные через `data-file`:
|
|
112
|
+
-- TODO описать полностью
|
|
113
|
+
|
|
114
|
+
## 🧹 Очистка и удаление
|
|
115
|
+
|
|
116
|
+
- **Удаление одного файла**: кнопка с `data-vg-dismiss="file"` → вызов `removeFile()`.
|
|
117
|
+
- **Очистка всех**: кнопка с `data-vg-dismiss="vg-files"` → `clear()`.
|
|
118
|
+
|
|
119
|
+
Поддержка подтверждения через `VGAlert` и уведомлений через `VGToast`.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 🧩 Расширяемость
|
|
124
|
+
|
|
125
|
+
- **FileUploader** — управляет загрузкой с поддержкой retry.
|
|
126
|
+
- **VGFilesTemplateRender** — рендеринг шаблонов.
|
|
127
|
+
- **Sortable (сортировка)** — подключается при необходимости.
|
|
128
|
+
- Поддержка кастомных иконок через `getSVG()`.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 🧰 API Методы
|
|
133
|
+
|
|
134
|
+
| Метод | Описание |
|
|
135
|
+
|------|--------|
|
|
136
|
+
| `upload(file)` | Загрузить один файл |
|
|
137
|
+
| `uploadAll(files)` | Загрузить все неотправленные файлы |
|
|
138
|
+
| `reload(button)` | Повторить загрузку файла |
|
|
139
|
+
| `removeFile(button)` | Удалить файл |
|
|
140
|
+
| `clear(full, uiOnly)` | Очистить список |
|
|
141
|
+
| `dispose()` | Полная деинициализация |
|
|
142
|
+
| `_triggerCallback(name, data)` | Вызов колбэка |
|
|
143
|
+
| `_route(params, cb)` | Выполнить AJAX-запрос |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 🌐 AJAX-интеграция
|
|
148
|
+
|
|
149
|
+
Поддерживает:
|
|
150
|
+
- Загрузку `POST /upload`
|
|
151
|
+
- Удаление `DELETE /files/{id}` или `POST /clear` с `ids[]`
|
|
152
|
+
- Сортировку `POST /sort` с массивом `ids`
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 🛑 Ограничения и валидация
|
|
157
|
+
|
|
158
|
+
- Проверка по размеру (одиночному и общему).
|
|
159
|
+
- Проверка по количеству файлов.
|
|
160
|
+
- Проверка MIME-типов.
|
|
161
|
+
- Отображение ошибок через `VGAlert` или консоль.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 🧾 Поддержка браузеров
|
|
166
|
+
|
|
167
|
+
- Современные браузеры (Chrome, Firefox, Safari, Edge)
|
|
168
|
+
- Требуется поддержка: `File`, `FormData`, `ES6+`, `CustomEvent`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 📚 Зависимости
|
|
173
|
+
|
|
174
|
+
- `VGFilesBase`, `VGFilesDroppable`, `VGFilesTemplateRender`, `FileUploader`
|
|
175
|
+
- `VGAlert`, `VGToast` — модули уведомлений
|
|
176
|
+
- `EventHandler`, `Selectors`, `Manipulator`, `Classes` — утилиты DOM
|
|
177
|
+
- `getSVG`, `lang_buttons`, `lang_messages` — компоненты интерфейса
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
✅ **Гибкий | Расширяемый | Локализуемый | Готов к production**
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 📝 Лицензия
|
|
186
|
+
|
|
187
|
+
MIT. Свободно использовать и модифицировать.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
📌 *Разработано в рамках фронтенд-системы VG Modules.*
|
|
192
|
+
> 🚀 Автор: VEGAS STUDIO (vegas-dev.com)
|
|
193
|
+
> 📍 Поддерживается в проектах VEGAS
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@keyframes stripes {
|
|
2
|
+
0% {
|
|
3
|
+
background-position: 0 0;
|
|
4
|
+
}
|
|
5
|
+
100% {
|
|
6
|
+
background-position: 60px 30px;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@keyframes flash {
|
|
11
|
+
0%, 100% { opacity: 1; }
|
|
12
|
+
50% { opacity: 0; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@keyframes spinner {
|
|
16
|
+
0% { transform: rotate(0deg); }
|
|
17
|
+
100% { transform: rotate(360deg); }
|
|
18
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Локальные миксины модуля (убирают дублирование между списками)
|
|
3
|
+
*/
|
|
4
|
+
@mixin vgfiles-sortable() {
|
|
5
|
+
&.with-sortable {
|
|
6
|
+
cursor: grab;
|
|
7
|
+
|
|
8
|
+
&:active {
|
|
9
|
+
cursor: grabbing;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&.dragging {
|
|
13
|
+
opacity: 0.6;
|
|
14
|
+
transform: scale(1.02);
|
|
15
|
+
z-index: 1000;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&.dragging-transparent {
|
|
20
|
+
pointer-events: none;
|
|
21
|
+
opacity: 0.3;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@mixin vgfiles-state() {
|
|
27
|
+
&.pending {
|
|
28
|
+
> * {
|
|
29
|
+
opacity: .32;
|
|
30
|
+
pointer-events: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.file-remove {
|
|
34
|
+
opacity: 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&.loading {
|
|
39
|
+
--vg-button-color: var(--vg-body-color);
|
|
40
|
+
|
|
41
|
+
> *:not(.file-remove) {
|
|
42
|
+
opacity: .52;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.file-remove {
|
|
47
|
+
opacity: 1;
|
|
48
|
+
pointer-events: none;
|
|
49
|
+
|
|
50
|
+
button {
|
|
51
|
+
i {
|
|
52
|
+
animation: spinner 1s linear infinite;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&.completed {
|
|
59
|
+
--vg-button-color: var(--vg-success);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&.failing {
|
|
63
|
+
--vg-button-color: var(--vg-danger);
|
|
64
|
+
|
|
65
|
+
> * {
|
|
66
|
+
opacity: .62;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.file-remove {
|
|
70
|
+
opacity: 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -1,28 +1,105 @@
|
|
|
1
1
|
$files-map: (
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
// label (уже используется в vgfiles.scss)
|
|
3
|
+
label-bg: #242424,
|
|
4
|
+
label-color: #ffffff,
|
|
5
|
+
label-border-color: #343434,
|
|
6
|
+
label-border-radius: 4px,
|
|
7
|
+
label-padding: 8px 24px,
|
|
8
|
+
label-padding-icon: 8px 16px,
|
|
9
|
+
|
|
10
|
+
// errors
|
|
11
|
+
errors-padding-y: 10px,
|
|
12
|
+
errors-font-size: 16px,
|
|
13
|
+
|
|
14
|
+
// drop zone
|
|
15
|
+
drop-bg: var(--vg-secondary-bg),
|
|
16
|
+
drop-border-width: 2px,
|
|
17
|
+
drop-border-style: dashed,
|
|
18
|
+
drop-border-color: var(--vg-secondary),
|
|
19
|
+
drop-radius: 8px,
|
|
20
|
+
drop-height: 200px,
|
|
21
|
+
drop-transition: all 0.2s ease,
|
|
22
|
+
|
|
23
|
+
drop-after-font-size: 14px,
|
|
24
|
+
drop-after-color: #007bff,
|
|
25
|
+
drop-after-bottom: 10px,
|
|
26
|
+
|
|
27
|
+
drop-hover-border-color: #007bff,
|
|
28
|
+
drop-hover-bg: #e3f2fd,
|
|
29
|
+
drop-hover-shadow: 0 0 10px rgba(0, 123, 255, 0.2),
|
|
30
|
+
|
|
31
|
+
drop-stripes-alpha: 0.03,
|
|
32
|
+
drop-stripes-size: 30px 30px,
|
|
33
|
+
drop-stripes-duration: 2s,
|
|
34
|
+
|
|
35
|
+
// drop message
|
|
36
|
+
drop-message-gap: 8px,
|
|
37
|
+
drop-message-font-size: 14px,
|
|
38
|
+
drop-message-line-height: 22px,
|
|
39
|
+
drop-message-color: #999999,
|
|
40
|
+
drop-message-icon-size: 48px,
|
|
41
|
+
drop-message-icon-color: #999999,
|
|
42
|
+
|
|
43
|
+
// drop list / file tiles
|
|
44
|
+
drop-list-gap: 8px,
|
|
45
|
+
drop-list-padding: 0.5rem,
|
|
46
|
+
drop-file-radius: 6px,
|
|
47
|
+
drop-file-height: 100px,
|
|
48
|
+
drop-file-flex: calc(25% - 6px),
|
|
49
|
+
|
|
50
|
+
drop-remove-offset: 10px,
|
|
51
|
+
drop-remove-size: 36px,
|
|
52
|
+
drop-remove-radius: 3px,
|
|
53
|
+
drop-remove-hover-bg: rgba(var(--vg-body-bg-rgb), .4),
|
|
54
|
+
|
|
55
|
+
// stat
|
|
56
|
+
stat-padding: 12px 8px,
|
|
57
|
+
stat-gap: 1rem,
|
|
58
|
+
stat-mb: 1rem,
|
|
59
|
+
stat-border-color: var(--vg-secondary-bg),
|
|
60
|
+
stat-title-fw: 600,
|
|
61
|
+
stat-count-font-size: 14px,
|
|
62
|
+
stat-count-ms: 6px,
|
|
63
|
+
stat-dismiss-font-size: 16px,
|
|
64
|
+
|
|
65
|
+
// info
|
|
66
|
+
info-mt: 1rem,
|
|
67
|
+
info-border-color: var(--vg-secondary-bg),
|
|
68
|
+
info-radius: 4px,
|
|
69
|
+
info-list-max-height: 360px,
|
|
70
|
+
|
|
71
|
+
info-gap: 8px,
|
|
72
|
+
info-padding: 8px,
|
|
73
|
+
info-border-bottom-color: var(--vg-secondary-bg),
|
|
74
|
+
info-hover-bg: rgba(var(--vg-secondary-bg-rgb), .4),
|
|
75
|
+
|
|
76
|
+
info-image-radius: 4px,
|
|
77
|
+
info-iteration-font-size: 16px,
|
|
78
|
+
info-name-font-size: 16px,
|
|
79
|
+
info-size-font-size: 14px,
|
|
80
|
+
|
|
81
|
+
info-remove-icon-size: 16px,
|
|
82
|
+
info-row-remove-size: 22px,
|
|
83
|
+
info-row-remove-icon-size: 10px,
|
|
84
|
+
|
|
85
|
+
// legacy (оставлено для совместимости со старым API темы)
|
|
86
|
+
info-mb: 10px,
|
|
87
|
+
info-title-color: darkgreen,
|
|
88
|
+
info-count-fw: 400,
|
|
89
|
+
info-count-fs: 14px,
|
|
90
|
+
info-count-color: #999999,
|
|
91
|
+
info-dismiss-fs: 14px,
|
|
92
|
+
info-dismiss-ms: 10px,
|
|
93
|
+
info-image-width: 100px,
|
|
94
|
+
info-image-me: 15px,
|
|
95
|
+
info-image-mb: 15px,
|
|
96
|
+
info-image-padding: 5px,
|
|
97
|
+
info-image-border: 1px solid #e0e0e0,
|
|
98
|
+
info-list-fs: 15px,
|
|
99
|
+
info-list-mt: 7px,
|
|
100
|
+
info-list-span-fs: 12px,
|
|
101
|
+
info-list-span-color: #999999,
|
|
102
|
+
info-list-span-me: 6px,
|
|
103
|
+
info-list-button-fs: 12px,
|
|
104
|
+
info-list-button-color: #999999,
|
|
28
105
|
);
|