96 Commits

Author SHA1 Message Date
erjemin 19a595fb10 minor: изменения в замерах времени исполнения вьюшки 2026-04-20 23:23:05 +03:00
erjemin 917d62cc21 mod: split catalog modules and refactor profile manufacture view 2026-04-20 22:23:42 +03:00
erjemin 71b5089a61 fix: явное указание типов 2026-04-20 01:02:16 +03:00
erjemin 9e27089638 minor: в отдельный catalog_profiles.py выделены все вьюхи для каталога профилей 2026-04-20 00:54:11 +03:00
erjemin af67b69418 mod: рефакторинг catalog_profile_model и обновление дорожной карты README 2026-04-20 00:43:27 +03:00
erjemin af2489f923 minor: ticks стал видимым 2026-04-20 00:33:13 +03:00
erjemin 0b6536b8f4 mod: simplify catalog profile views 2026-04-19 23:43:13 +03:00
erjemin c930e059a0 mod: catalog_profile и документация 2026-04-18 15:39:39 +03:00
erjemin c0b41cd866 add: SITEMAP_RUNBOOK.md; mod: README.md — обновлена документация проекта 2026-04-18 13:48:28 +03:00
erjemin b348c8fe81 mod: rework sitemap generation and seo coverage 2026-04-18 13:28:15 +03:00
erjemin e7da2cdeb9 mod: migrate to poetry and add django debug toolbar for dev 2026-04-17 16:07:19 +03:00
erjemin d5719015b0 mod: switch secrets config to .env 2026-04-17 15:18:05 +03:00
erjemin bcc10de4d4 minor: комментарии fix имя файла 2026-04-16 21:28:18 +03:00
erjemin 55f9a74231 del: нет логам в репозитории 2026-04-16 21:20:24 +03:00
erjemin 49c19d9f92 mod: добавлен сервис пересчета рейтинга 2026-04-16 21:15:19 +03:00
erjemin 67a8c093f5 mod: add favicon 2026-04-16 21:13:53 +03:00
erjemin e0a5a5739b minor: del print 2026-04-16 21:12:31 +03:00
erjemin 3e67d6cf71 mod: switch dev to sqlite and add static fallback paths 2026-04-16 21:10:58 +03:00
erjemin 917bcb42c8 minor: del print 2026-04-16 20:37:45 +03:00
erjemin 5bdb97f5e8 add: initial commit — Django 4.1 project (2022 version), docs, security templates 2026-04-16 15:55:21 +03:00
erjemin e2091b72b1 Static: недостающие файлы из error.log 2023-03-04 00:20:53 +03:00
erjemin 446cbe8c5c SEO: Title & Description 2023-03-04 00:19:41 +03:00
erjemin bdca8dfc6a SEO: Title & Description (каталог профилей) 2023-02-17 22:01:15 +03:00
erjemin 111dd7bd33 SEO: Title & Description 2023-02-17 19:18:18 +03:00
erjemin 57a522f4b7 minor: недостающая статика (png) 2023-02-17 19:12:02 +03:00
erjemin 2b37f709a9 minor: недостающая статика (css, js) 2023-02-15 23:51:25 +03:00
erjemin f480dc3666 minor: favicon.svg 2023-02-10 20:39:25 +03:00
erjemin 2da036e4e0 minor: убрал отладочный print() 2023-01-29 23:01:26 +03:00
erjemin 28620ce2a9 minor: excel-шаблоны для загрузки и заполнения 2023-01-29 22:57:14 +03:00
erjemin 574ae84321 minor: первый экран, изменен текст (SEO) 2023-01-29 18:20:48 +03:00
erjemin 796cb89525 minor: кеш картинок и шаблонов (++) 2023-01-19 00:52:52 +03:00
erjemin 0e8839bf18 minor: кеш картинок и шаблонов (+) 2023-01-19 00:46:06 +03:00
erjemin dbd622e456 minor: кеш картинок и шаблонов 2023-01-18 00:38:03 +03:00
erjemin 741dd2685e minor: вот так работает в продашн 2023-01-18 00:15:58 +03:00
erjemin c01873144e ini для uwsgi (tested) 2023-01-14 04:22:25 +03:00
erjemin 8387d36abf конфиг для nginx (tested) 2023-01-14 04:21:41 +03:00
erjemin 2bc0869104 обновленные пакеты окружения для dev на mac-m1 (python 3.10.9) 2023-01-14 04:04:08 +03:00
erjemin 8c7972178c имя файла к touch-reload для девопа 2023-01-14 04:02:05 +03:00
erjemin c338a17dd8 передергивает touch-reload при изменении кеш-шаблона 2023-01-14 03:49:55 +03:00
erjemin 3cc4ae39f7 minor 2023-01-14 02:42:49 +03:00
erjemin d789b2443a пакеты окружения (дев/прод) 2023-01-14 02:19:58 +03:00
erjemin 25beecdf60 пакеты окружения (дев/прод) 2023-01-14 02:19:39 +03:00
erjemin 5eb2f304a3 доки по профилям монблан 2023-01-14 02:18:46 +03:00
erjemin 0246c1de8c minor (error -- был пустой slag для текущей серии) 2023-01-14 01:43:14 +03:00
erjemin 4196cd64d8 minor (без переменной template) 2023-01-14 01:17:59 +03:00
erjemin 60b6582f1b minor (исправлены типы переменных для совместимости с продакшн) 2023-01-13 22:23:24 +03:00
erjemin 4a91928bc7 картинки для блога 2023-01-13 22:13:17 +03:00
erjemin b322331366 картинки к сериям домов 2023-01-13 22:08:21 +03:00
erjemin e041110059 логотипы компаний из базы 2023-01-13 21:57:56 +03:00
erjemin ae1b851db7 touch-reload.txt 2023-01-13 19:46:51 +03:00
erjemin 28aa35d617 nginx conf-file for production 2023-01-13 19:18:04 +03:00
erjemin b296ad79e9 favicon & other static 2023-01-13 17:27:16 +03:00
erjemin fbea58b1c4 Служебное -- формирование sitemap-файлов 2023-01-10 01:21:28 +03:00
erjemin 30084dd6ac minor -- точные размеры в мм. в заголовке и крошках 2023-01-09 23:30:49 +03:00
erjemin c961b64036 minor -- размеры и мм. тоже 2023-01-09 23:29:57 +03:00
erjemin ad74f0a51e Служебное -- главные служебные (если есть и нет аутентификации) 2023-01-08 19:41:12 +03:00
erjemin 78ec6077b6 Служебное -- главна и аутентификация 2023-01-08 19:36:48 +03:00
erjemin c68fa5be07 Служебное -- страница для тестирования верстки текста в блоге 2023-01-08 18:14:27 +03:00
erjemin ee1dd31d54 Переадресация для старых, внешних ссылок 2023-01-08 01:38:14 +03:00
erjemin 6066e5df29 Подгружаемый блок с детальным описанием состава рейтинга -- готово 2023-01-07 04:51:11 +03:00
erjemin 8704f4125b удалён лишний шаблон 2023-01-07 03:42:47 +03:00
erjemin 2777f3fde2 Вьюшка и шаблон: сравнение оконных наборов -- готово 2023-01-07 03:42:14 +03:00
erjemin 4b9ca319f9 кеш картинки со схемами открывания 2022-12-31 13:54:15 +03:00
erjemin 56d7af5c9d перенос и переименование шаблонов 2022-12-31 05:13:12 +03:00
erjemin 0368c1c34e Вьюшка: подгружаемые фреймы с ценами одного типового окна -- готово 2022-12-31 05:01:39 +03:00
erjemin fbdf95b66f minor 2022-12-31 04:44:38 +03:00
erjemin 8fdaf6935e minor (переименование шаблонов) 2022-12-31 04:44:11 +03:00
erjemin 8272bdb25f Вьюшка: Подгружаемых фреймов ценовых предложений -- minor 2022-12-31 04:36:40 +03:00
erjemin 6a4c315cdc Вьюшка: Подгружаемых фреймов ценовых предложений -- готово 2022-12-31 04:33:59 +03:00
erjemin f2c89abe1c Вьюшка : Выдача предложений -- minor (убраны отладочные print) 2022-12-31 02:57:49 +03:00
erjemin 37a605ef09 Вьюшка и шаблоны: Выдача предложений -- готово 2022-12-31 02:55:09 +03:00
erjemin 28a680fdf1 Отдельный каталог для шаблонов выпадающей окон -- minor 2022-12-30 19:58:56 +03:00
erjemin 9bcbc73602 Выпадающее окно после ввода адреса -- готово 2022-12-30 19:52:42 +03:00
erjemin 8ca1f5b36e Кеш-картинки схем открывания (большие и маленькие) 2022-12-30 15:31:17 +03:00
erjemin 6c4dcd1cb7 Ценовая выдача для одного окна 2022-12-30 15:30:05 +03:00
erjemin 5a38181cd3 Оптимизация + на мини-картинках схем открывания рисуется спейсер и москитная сетка 2022-12-29 17:25:41 +03:00
erjemin 5738ee9c9e Шаблон: "Каталог / Производители и поставщики окон / Компания" -- minor 2022-12-29 16:10:26 +03:00
erjemin 9535424e6a Шаблон: "Каталог / Производители и поставщики окон / Компания" -- minor: seo, Yandex.map 2022-12-29 15:56:14 +03:00
erjemin 4e03fead67 Вьюшка и шаблон: "Каталог / Производители и поставщики окон / Компания" -- готово 2022-12-29 15:46:16 +03:00
erjemin 5de28c8bfb Вьюшка: "Каталог / Производители и поставщики окон" -- minor 2022-12-29 00:18:53 +03:00
erjemin de45931ff4 Вьюшка и шаблон: "Каталог / Производители и поставщики окон" -- готово 2022-12-29 00:17:27 +03:00
erjemin d27d0e7173 Шаблоны prerender: "Каталог / Типовые серии зданий / Информация по серии" -- minor, SEO 2022-12-27 15:21:38 +03:00
erjemin f3a8a65afe Шаблон: "Каталог / Типовые серии зданий / Информация по серии" и "Статистика" -- minor seo 2022-12-27 15:19:08 +03:00
erjemin 72b71c7810 Шаблон и css: "Каталог / Оконные проёмы и балконные блоки" -- минор 2022-12-27 14:57:34 +03:00
erjemin 6bd8143d83 avatar image (для блога и "о компании") 2022-12-27 14:17:04 +03:00
erjemin a970b7109b prerender small-image со схемами открывания (2022-12-27) 2022-12-27 14:15:16 +03:00
erjemin 99b8ba80d5 Вьюшка и шаблон: "Каталог / Оконные проёмы и балконные блоки" -- готово 2022-12-27 14:13:29 +03:00
erjemin 7cc438d1c5 миграции 2022-12-26 18:30:26 +03:00
erjemin 034ec20c26 Про кеширующие шаблоны 2022-12-26 18:30:09 +03:00
erjemin 90ddc0d88c Вьюшка: "Информация по всем сериям домой" -- minor
перенесли одну формирования навигации по сериям
2022-12-26 18:28:52 +03:00
erjemin 6e92eca67a prerender image со схемами открывания (2022-12-26 минор) 2022-12-26 18:13:57 +03:00
erjemin 6a9c0e4568 Шаблоны prerender: "Каталог / Типовые серии зданий / Информация по серии" -- minor 2022-12-26 18:08:33 +03:00
erjemin 265732bae8 Шаблон: "Каталог / Типовые серии зданий / Информация по серии" -- minor (data, last modified, еxpires) 2022-12-26 18:04:35 +03:00
erjemin cded4e407e prerender image со схамами открывания (2022-12-26) 2022-12-26 18:02:20 +03:00
erjemin f996dd891e prerender image со схамами открывания (2022-12-26) 2022-12-26 17:42:59 +03:00
erjemin 748a1882e5 Вьюшка: "Каталог / Типовые серии зданий / Информация по серии" -- prerender template (2022-12-26) -
Эти шаблоны надо периодически удалять. Они нужны для скорости. Но если меняются данные по серии, размерам окон, появляются новые ком.предложения -- их надо удалять и тогда построятся новые.
2022-12-26 17:34:28 +03:00
65 changed files with 14773 additions and 1537 deletions
+30 -13
View File
@@ -1,5 +1,6 @@
# Django Configuration Example
# Копируйте этот файл в .env.local и заполните реальные значения
# Все настройки читаются из переменных окружения (DEV/PROD без распознавания хоста)
# Для локальной разработки можно скопировать файл в .env.local и экспортировать его.
# ============================================================================
# DJANGO
@@ -15,19 +16,35 @@ DEBUG=False
# Допустимые хосты (разделены запятой без пробелов)
ALLOWED_HOSTS=localhost,127.0.0.1,yourdomain.com
# Базовый публичный URL сайта (используется для абсолютных URL в sitemap.xml)
SITE_BASE_URL=https://yourdomain.com
# Админы для email-оповещений Django (формат: Имя:email,Имя2:email2)
ADMINS=Admin:admin@example.com
# ============================================================================
# DATABASE
# ============================================================================
# Database backend (по умолчанию mysql)
DATABASE_ENGINE=django.db.backends.mysql
# Database backend (по умолчанию SQLite)
DATABASE_ENGINE=django.db.backends.sqlite3
# Database connection
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_NAME=django_oknardia
DATABASE_USER=web
DATABASE_PASSWORD=your-db-password-here
# Имя/путь базы данных:
# - для SQLite: только имя файла (полный путь соберется в settings.py через PROJECT_ROOT/database)
# - для MySQL/MariaDB: имя базы
DATABASE_NAME=oknadria.sqlite3
# Для MySQL/MariaDB (используются, если DATABASE_ENGINE=django.db.backends.mysql)
# DATABASE_HOST=localhost
# DATABASE_PORT=3306
# DATABASE_USER=name-for-db-user
# DATABASE_PASSWORD=your-db-password-here
# Пути вычисляются автоматически внутри settings.py от PROJECT_ROOT
TOUCH_RELOAD=/app/logs/touch-reload.txt
# Подкаталог в MEDIA_ROOT, где хранится кеш sitemap-файлов
SITEMAP_SUBDIR=_serv_sitemap
# ============================================================================
# EMAIL
@@ -40,6 +57,7 @@ EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_USE_SSL=False
EMAIL_HOST_USER=your-email@example.com
EMAIL_HOST_PASSWORD=your-email-password
@@ -100,7 +118,7 @@ LOG_LEVEL=INFO
# ============================================================================
# 1. Скопируйте этот файл:
# cp .env.example .env.local
# cp .env.sample .env.local
#
# 2. Отредактируйте значения в .env.local:
# nano .env.local
@@ -108,9 +126,8 @@ LOG_LEVEL=INFO
# 3. Убедитесь, что .env.local в .gitignore:
# grep ".env" .gitignore
#
# 4. Используйте python-dotenv для загрузки переменных в settings.py:
# from dotenv import load_dotenv
# load_dotenv()
# 4. Экспортируйте переменные перед запуском Django:
# set -a; source .env.local; set +a
#
# ВАЖНО:
# - НИКОГДА не коммитьте .env.local или файлы с реальными значениями в git!
+32 -1
View File
@@ -132,4 +132,35 @@ venv.bak/
dmypy.json
# Pyre type checker
.pyre/
.pyre/
# MacOS specific files
.DS_Store
# Database dumps and backups (CRITICAL - NEVER commit production data!)
SQL/
*.sql
*.dump
*.backup
*.sql.gz
db.json
db.json.zip
# API keys, certificates, and credentials
*.key
*.pem
*.p12
*.p8
*.crt
*.cert
# IDE and editor specific
.vscode/settings.json
.idea/vcs.xml
.idea/inspectionProfiles/
# Project specific ignore patterns
.github/
.log/
.logs/
sitemap*.xml
+1
View File
@@ -213,6 +213,7 @@ python manage.py collectstatic # собрать статику для
5. **Foreign Key ON_DELETE**: используется в основном `DO_NOTHING` и `SET_NULL`, будь осторожен при удалении
6. **Двойной хост**: убедись, что используешь правильные переменные из `my_secret.py` для текущей машины
7. **Индексирование БД**: большинство полей для поиска уже имеют `db_index=True`, но проверь при добавлении фильтров
8. **SEO-даты и свежесть контента**: при переделке вьюх/шаблонов отдельно проверяй, нужны ли ещё `last_update`, `PUB_DAT`, `Date4Meta` и `Last4Meta`; если дата не участвует в смысловой логике страницы, лучше оставить базовые `{% now %}` из `base.html`, а не тащить лишний контекст во вьюху и не нагружать бекенд.
## Реферальные ссылки (для более глубокого изучения)
+35 -1
View File
@@ -1,6 +1,40 @@
# Оконный агрегатор «Окнардия»
### Переделка под Python 3.8 и Django 4.1
### Переделка под Python 3.12 и Django 5.2
### Актуальная памятка дорожная карта
#### Готово:
* Изменена база данных используемая в проекте (SQLite вместо MariaDB).
* Окружение проекта теперь настраивается через `poetry` вместо `pip` и `requirements.txt`.
* Проект получает настройки и секреты через переменные окружения (`.env`) вместо `my_secret*.py`.
* Рефакторинг создания `sitemap.xml`: raw ⟶ ORM, создание через Django-команду `generate_sitemaps` в медиа-файлы.
* Рефакторинг URL `/catalog/profil/`: raw SQL ⟶ ORM, убран `last_update`, измененs SEO `description` и `keywords`.
* Распилен `oknardia/web/catalog.py` на тематические модули (`catalog_companies.py`, `catalog_profiles.py`, `catalog_series.py`, `catalog_openings.py`) с вынесением общей логики в `catalog_utils.py`; маршруты обновлены без изменения внешних URL.
* Рефакторинг `catalog_profile_model` (`/catalog/profile/...`): raw SQL ⟶ ORM, упрощена логика, вынесены helper-функции, сокращено дублирование расчёта цветов рейтинга, нормализована подготовка `LIST_OTHER`/`MERCHANTS`/`PROFILES`/`PROFILE_DETAIL`, сохранена совместимость шаблонов.
* Рефакторинг `catalog_profile_manufacture` (`/catalog/profile/<id>-<manufacturer>`): упрощена валидация URL, убран дублирующий код маппинга для `PROFILES` и `MERCHANTS` через общие хелперы, стандартизирован хвост контекста (`LAST_VISIT`, `LOG_VISIT`, `ticks`) через `_append_visit_context`.
#### Планы, задачи, маркеры и идеи на будущее:
* Переделать все raw SQL-запросы на ORM (для перехода на SQLite и для лучшей поддержки разных СУБД в будущем).
* Для легаси-страниц (шаблоны и вьюхи) поэтапно проверять (если нужно убирать) старые SEO-хвосты вроде `last_update` / `PUB_DAT` / `Date4Meta` / `Last4Meta`: если дата не несёт смысловой нагрузки, лучше оставлять базовые `{% now %}` из `base.html`, а не тащить лишний контекст во вьюху.
* Шаблоны `report/report_last_user_visit.html` и `report/report_log_user_visit.html` сделать с конентом
подгружаемым через AJAX (использовать HTMX, напрмемер) и убрать вызовы `get_last_user_visit_list` и `get_last_all_user_visit_list` их соответствующих вьюх. Это должно разгрузить бекенд и, возможно, сделать кеширование.
* Упаковать всё в контейнеры (Django + Gunicorn + WhiteNoise...
См. также:
* [`AGENTS.md`](AGENTS.md) – контекст проекта для AI-ассистентов (архитектура, конвенции, рабочие сценарии).
* [`SETUP.md`](SETUP.md) – пошаговая настройка окружения, запуск проекта и базовые команды разработки.
* Сервисные утилиты:
- [`SITEMAP_RUNBOOK.md`](SITEMAP_RUNBOOK.md) – sitemap (генерация, веса, cron, nginx)
---
Легаси-материалы старого README, которые могут быть полезны для понимания устройства проекта и его
администрирования, а также для будущей реорганизации документации.
### Немного о механике кеширования:
+102
View File
@@ -0,0 +1,102 @@
# SITEMAP_RUNBOOK.md
## Что изменено
- Генерация sitemap выполняется только через custom management command: `generate_sitemaps`.
- Генерация через интерфейс `/service/*` и URL-роуты удалена.
- Файлы sitemap хранятся в media-каталоге: `MEDIA_ROOT/_serv_sitemap`.
- `robots.txt` указывает на `https://oknardia.ru/media/_serv_sitemap/sitemap.xml`.
- Глубина `compare_offers` по-молчанию ограничена диапазоном `2..4`.
- В `lastmod` записывается только дата (`YYYY-MM-DD`), без времени.
## Что сейчас входит в sitemap
- главная страница `/`;
- список и карточки блога (`/blog/Pn`, `/blogpost/...`);
- каталог профилей: корень, производители и карточки моделей;
- каталог серий домов и детальные страницы типовых серий;
- каталог оконных компаний и карточки брендов;
- каталог стандартных оконных проёмов;
- страница рейтинга профилей;
- страницы цен по адресам и по одиночным проёмам;
- страницы `compare_offers` (с `changefreq=monthly` и пониженным приоритетом).
## Ручной запуск
Из каталога `oknardia/`:
```bash
poetry run python manage.py generate_sitemaps
```
С явными параметрами:
```bash
poetry run python manage.py generate_sitemaps \
--compare-min-depth 2 \
--compare-max-depth 4 \
--max-items 40000 \
--max-file-size 5242880 \
--max-files-qty 998
```
## Параметры команды
- `--compare-min-depth` — минимальная глубина комбинаций `compare_offers` (по умолчанию `2`).
- `--compare-max-depth` — максимальная глубина комбинаций `compare_offers` (по умолчанию `4`).
- `--max-items` — лимит URL в одном sitemap-файле (по умолчанию `40000`).
- `--max-file-size` — лимит размера sitemap-файла в байтах (по умолчанию `5242880`).
- `--max-files-qty` — лимит количества вложенных sitemap-файлов (по умолчанию `998`).
## Важные переменные окружения
- `SITE_BASE_URL` — базовый URL сайта (например, `https://oknardia.ru`).
- `SITEMAP_SUBDIR` — подкаталог в `MEDIA_ROOT` для sitemap (по умолчанию `_serv_sitemap`).
## Что добавить в контейнер
Минимально (после миграций и перед запуском веб-процесса):
```bash
poetry run python manage.py generate_sitemaps || true
```
> `|| true` можно убрать, если хотите падать при любой ошибке генерации.
## Вариант для расписания (когда определитесь)
Можно запускать команду по расписанию любым внешним scheduler:
```bash
poetry run python manage.py generate_sitemaps
```
- через cron хоста,
- или через отдельный scheduler-контейнер.
### Пример внешнего cron на хосте
Пример строки для `crontab -e` на хост-машине (запуск раз в 3 дня в 03:30) с явным именем контейнера `oknarida-backend`:
```bash
30 3 */3 * * /usr/bin/docker exec -i oknarida-backend /bin/sh -lc 'cd /app/oknardia && poetry run python manage.py generate_sitemaps --compare-min-depth 2 --compare-max-depth 4 --max-items 40000 --max-file-size 5242880 --max-files-qty 998' >> /var/log/oknardia-sitemap.log 2>&1
```
> Если путь проекта внутри контейнера отличается от `/app/oknardia`, просто замени `cd /app/oknardia` на фактический путь.
## Прокси/NGINX
Можно хранить физические файлы в media-volume и при этом проксировать/алиасить корневой URL `sitemap.xml` на файл из `media/_serv_sitemap`.
Допустимо, что файл доступен по двум URL (корневой и media), но в `robots.txt` должен быть указан один канонический вариант.
### NGINX snippet (alias для корневого sitemap)
```nginx
# Корневой sitemap.xml (для привычного для поисковиков URL)
location = /sitemap.xml {
alias /<путь-к-каталогку-с-докер-приложением>/media/_serv_sitemap/sitemap.xml;
default_type application/xml;
add_header Cache-Control "public, max-age=300";
}
```
+3
View File
@@ -0,0 +1,3 @@
# Это папака для хранения базы данных SQLite, не должна быть в репозитории.
*.*
*
-1
View File
@@ -1 +0,0 @@
1
-185
View File
@@ -1,185 +0,0 @@
# -*- coding: utf-8 -*-
"""
ШАБЛОН для my_secret.py
ИНСТРУКЦИЯ: скопируйте этот файл в my_secret.py и заполните реальные значения.
Пример:
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
# затем отредактируйте значения в my_secret.py
ВАЖНО: my_secret.py НИКОГДА не должен быть в git!
Используйте .gitignore для исключения файла.
"""
# ============================================================================
# РАЗРАБОТКА (DEV) - Хосты и сетевые настройки
# ============================================================================
# Хосты на которых может работать приложение (разработка)
MY_ALLOWED_HOSTS = [
'127.0.0.1',
'localhost',
'your-dev-hostname.local', # ИЗМЕНИТЕ на ваше имя хоста
]
# Допустимые хосты для разработки
MY_HOST_HOME1 = 'your-dev-hostname-windows' # ИЗМЕНИТЕ
MY_HOST_HOME2 = 'your-dev-hostname-mac' # ИЗМЕНИТЕ
MY_HOST_DEV = [MY_HOST_HOME1, MY_HOST_HOME2]
# Хосты для продакшена (заполнять с осторожностью)
MY_HOST_PROD = [] # На продакшене используйте переменные окружения!
# ============================================================================
# БЕЗОПАСНОСТЬ - Django SECRET_KEY
# ============================================================================
# SECURITY WARNING: keep the secret key used in production secret!
# Сгенерируйте новый ключ с помощью:
# python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
MY_SECRET_KEY = 'ЗАПОЛНИТЕ_СЛУЧАЙНОЙ_СТРОКОЙ_БОЛЬШОЙ_ДЛИНЫ'
# ============================================================================
# АДМИНИСТРАТОРЫ - для оповещений об ошибках
# ============================================================================
MY_ADMINS = (
('Your Name', 'your-email@example.com'),
('Admin Name', 'admin@example.com'),
)
# ============================================================================
# ПУТИ К ФАЙЛАМ - разработка
# ============================================================================
# путь к каталогу media (статика, для web-сервера nginx или apache)
MY_MEDIA_ROOT_DEV1 = 'M:\\path\\to\\your\\media\\' # Windows (если применимо)
MY_MEDIA_ROOT_DEV2 = '/path/to/your/media/' # Mac/Linux - ИЗМЕНИТЕ!
# путь к каталогу static (статика, для web-сервера nginx или apache)
MY_STATIC_ROOT_DEV1 = 'M:\\path\\to\\your\\static' # Windows (если применимо)
MY_STATIC_ROOT_DEV2 = '/path/to/your/static' # Mac/Linux - ИЗМЕНИТЕ!
# путь для кэш-блоков шаблонов
MY_STATIC_BASE_PATH_DEV1 = MY_STATIC_ROOT_DEV1
MY_STATIC_BASE_PATH_DEV2 = MY_STATIC_ROOT_DEV2
# путь для sitemap файлов
MY_SITEMAP_ROOT_DEV1 = 'M:\\path\\to\\your\\public\\' # Windows (если применимо)
MY_SITEMAP_ROOT_DEV2 = '/path/to/your/public/' # Mac/Linux - ИЗМЕНИТЕ!
# ============================================================================
# ПУТИ К ФАЙЛАМ - продакшен
# ============================================================================
MY_MEDIA_ROOT_PROD = '/home/web/oknardia-ru/public/media/' # ЗАПОЛНИТЕ!
MY_STATIC_ROOT_PROD = '/home/web/oknardia-ru/public/static' # ЗАПОЛНИТЕ!
MY_STATIC_BASE_PATH_PROD = MY_STATIC_ROOT_PROD
MY_SITEMAP_ROOT_PROD = '/home/web/oknardia-ru/public/' # ЗАПОЛНИТЕ!
# ============================================================================
# EMAIL - Почтовый сервер (разработка)
# ============================================================================
# Email адреса для разработки
MY_EMAIL_DEV = 'dev-email@example.com'
MY_EMAIL_FROM_DEV = 'dev-email@example.com'
MY_EMAIL_HOST_USER_DEV = 'your-email@smtp.example.com' # ЗАПОЛНИТЕ!
MY_EMAIL_HOST_PASSWORD_DEV = 'YOUR_EMAIL_PASSWORD' # ЗАПОЛНИТЕ!
MY_EMAIL_HOST_DEV = 'smtp.example.com' # ЗАПОЛНИТЕ! (например: smtp.mail.ru)
MY_EMAIL_PORT_DEV = 587 # ЗАПОЛНИТЕ! (обычно 587 или 2525)
# ============================================================================
# EMAIL - Почтовый сервер (продакшен)
# ============================================================================
MY_EMAIL_PROD = MY_EMAIL_DEV
MY_EMAIL_FROM_PROD = MY_EMAIL_FROM_DEV
MY_EMAIL_HOST_USER_PROD = MY_EMAIL_HOST_USER_DEV # На продакшене используйте env переменные!
MY_EMAIL_HOST_PASSWORD_PROD = MY_EMAIL_HOST_PASSWORD_DEV # На продакшене используйте env переменные!
MY_EMAIL_HOST_PROD = MY_EMAIL_HOST_DEV
MY_EMAIL_PORT_PROD = MY_EMAIL_PORT_DEV
# ============================================================================
# БД MySQL/MariaDB - разработка
# ============================================================================
MY_DATABASE_HOST_DEV1 = 'localhost' # Офисный сервер разработки - ИЗМЕНИТЕ!
MY_DATABASE_HOST_DEV2 = 'localhost' # Домашний сервер разработки - ИЗМЕНИТЕ!
MY_DATABASE_NAME_DEV = 'django_oknardia_dev' # ИЗМЕНИТЕ если нужно
MY_DATABASE_PORT_DEV = '3306' # Стандартный порт MySQL
MY_DATABASE_USER_DEV = 'web' # ИЗМЕНИТЕ если нужно
MY_DATABASE_PASSWORD_DEV = 'YOUR_DB_PASSWORD' # ЗАПОЛНИТЕ!
# ============================================================================
# БД MySQL/MariaDB - продакшен
# ============================================================================
MY_DATABASE_HOST_PROD = 'localhost' # ЗАПОЛНИТЕ! (на продакшене)
MY_DATABASE_NAME_PROD = 'django_oknardia_prod' # ЗАПОЛНИТЕ!
MY_DATABASE_PORT_PROD = '3306'
MY_DATABASE_USER_PROD = 'web'
# ВНИМАНИЕ: На продакшене используйте переменные окружения или менеджер секретов!
MY_DATABASE_PASSWORD_PROD = '' # ОСТАВЬТЕ ПУСТО! Используйте переменные окружения!
# ============================================================================
# API ключи - Google Captcha
# ============================================================================
# Получите ключи на https://www.google.com/recaptcha/admin
# ВАЖНО: Никогда не коммитьте реальные ключи в git!
# PRIVATE ключ - это СЕКРЕТ, держите его в безопасности!
MY_CAPTCHA_PUBLIC_KEY = 'YOUR_CAPTCHA_PUBLIC_KEY_HERE' # ЗАПОЛНИТЕ!
MY_CAPTCHA_PRIVATE_KEY = 'YOUR_CAPTCHA_PRIVATE_KEY_HERE' # ЗАПОЛНИТЕ! (СЕКРЕТ!)
# ============================================================================
# API ключи - Yandex Maps
# ============================================================================
# Получите ключ на https://developer.tech.yandex.ru/
MY_YANDEX_MAPS_API_KEY = 'YOUR_YANDEX_MAPS_API_KEY'
# ============================================================================
# uWSGI - Touch-reload файл (для перезагрузки при изменении кода)
# ============================================================================
MY_TOUCH_RELOAD_DEV1 = 'M:\\path\\to\\touch-reload.txt' # Windows (если применимо)
MY_TOUCH_RELOAD_DEV2 = '/path/to/logs/touch-reload.txt' # Mac/Linux - ИЗМЕНИТЕ!
MY_TOUCH_RELOAD_PROD = '/home/web/oknardia-ru/logs/touch-reload.txt' # ЗАПОЛНИТЕ!
# ============================================================================
# ИНСТРУКЦИЯ ПО ЗАПОЛНЕНИЮ
# ============================================================================
"""
1. СКОПИРУЙТЕ этот файл:
cp oknardia/oknardia/my_secret.py.template oknardia/oknardia/my_secret.py
2. ОТРЕДАКТИРУЙТЕ значения, помеченные ИЗМЕНИТЕ! или ЗАПОЛНИТЕ!
3. УБЕДИТЕСЬ, что мой_secret.py в .gitignore:
grep my_secret .gitignore
4. НИКОГДА не коммитьте my_secret.py в git!
5. На ПРОДАКШЕНЕ используйте переменные окружения:
export DJANGO_SECRET_KEY="..."
export DATABASE_PASSWORD="..."
и т.д.
СОВЕТЫ:
- Сгенерируйте новый SECRET_KEY с помощью Python:
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
- Используйте менеджер паролей (LastPass, 1Password, Vault) для хранения учетных данных
- Регулярно меняйте пароли БД и API ключи
- На продакшене используйте отдельные более сильные пароли
"""
+92 -54
View File
@@ -12,32 +12,49 @@ https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
from oknardia.my_secret import *
import socket
import environ
def _env_admins(raw_items: list[str]) -> tuple[tuple[str, str], ...]:
# Формат: "Имя1:email1,Имя2:email2"
admins: list[tuple[str, str]] = []
for item in raw_items:
if ":" not in item:
continue
admin_name, admin_email = item.split(":", maxsplit=1)
admin_name = admin_name.strip()
admin_email = admin_email.strip()
if admin_name and admin_email:
admins.append((admin_name, admin_email))
return tuple(admins)
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
PROJECT_ROOT = BASE_DIR.parent
PUBLIC_ROOT = PROJECT_ROOT / 'public'
STATIC_SOURCE_ROOT = PUBLIC_ROOT / 'static'
env = environ.Env()
environ.Env.read_env(str(PROJECT_ROOT / '.env'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-pd&1$j6z*1w#(j*16b+(@@#&2)+@x^^ot4)zqt-e67*1+$^qch'
SECRET_KEY = env(
'DJANGO_SECRET_KEY',
default='django-insecure-pd&1$j6z*1w#(j*16b+(@@#&2)+@x^^ot4)zqt-e67*1+$^qch',
)
# SECURITY WARNING: don't run with debug turned on in production!
# ПРЕДУПРЕЖДЕНИЕ БЕЗОПАСНОСТИ: не работайте в режиме DEBUG в продашене!
if socket.gethostname() in MY_HOST_DEV:
DEBUG = TEMPLATE_DEBUG = True
else:
# Все остальные хосты (подразумевается продакшн)
DEBUG = TEMPLATE_DEBUG = True
# DEBUG = TEMPLATE_DEBUG = False
DEBUG = TEMPLATE_DEBUG = env.bool('DEBUG', default=False)
ALLOWED_HOSTS = MY_ALLOWED_HOSTS
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=['127.0.0.1', 'localhost'])
# Настройки сообщений об ошибках когда все упало и т.п.
ADMINS = MY_ADMINS
ADMINS = _env_admins(env.list('ADMINS', default=[]))
# Application definition
@@ -51,7 +68,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.humanize',
# 'django.contrib.sitemaps',
'django.contrib.sitemaps',
'oknardia.apps.OknardiaConfig',
'web.apps.WebConfig',
@@ -67,6 +84,13 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# Разрешенные IP для отладки (нужно для django-debug-toolbar).
INTERNAL_IPS = env.list('INTERNAL_IPS', default=['127.0.0.1', 'localhost'])
if DEBUG:
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware', *MIDDLEWARE]
ROOT_URLCONF = 'oknardia.urls'
TEMPLATES = [
@@ -115,61 +139,75 @@ DATETIME_FORMAT = 'Y-m-d H:i:s'
# Статические файлы (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/'
MEDIA_URL = 'media/'
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
if socket.gethostname() in MY_HOST_DEV: # DEBUG: заменяем настройки прода, на настройки девопа
MEDIA_ROOT = MY_MEDIA_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_MEDIA_ROOT_DEV2
SITEMAP_ROOT = MY_SITEMAP_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_SITEMAP_ROOT_DEV2
# STATIC_ROOT = MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2
STATICFILES_DIRS = [
MY_STATIC_ROOT_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_ROOT_DEV2,
]
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_STATIC_BASE_PATH_DEV2
MEDIA_ROOT = str(PUBLIC_ROOT / 'media')
# STATIC_ROOT отделен от исходной статики, чтобы избежать staticfiles.E002.
STATIC_ROOT = str(PUBLIC_ROOT / 'static_collected')
# Базовый URL сайта нужен для абсолютных URL в sitemap.xml.
SITE_BASE_URL = env('SITE_BASE_URL', default='https://oknardia.ru').rstrip('/')
# Файлы sitemap храним в media-volume, чтобы переживали пересоздание контейнера.
SITEMAP_SUBDIR = env('SITEMAP_SUBDIR', default='_serv_sitemap').strip('/ ')
SITEMAP_ROOT = str(Path(MEDIA_ROOT) / SITEMAP_SUBDIR)
SITEMAP_URL_PREFIX = f"{MEDIA_URL.rstrip('/')}/{SITEMAP_SUBDIR}"
SITEMAP_INDEX_URL = f"{SITE_BASE_URL}{SITEMAP_URL_PREFIX}/sitemap.xml"
# Каталоги, откуда Django читает исходную статику в DEBUG-режиме.
STATICFILES_DIRS = [
str(STATIC_SOURCE_ROOT)
] if STATIC_SOURCE_ROOT.is_dir() else []
# Путь к каталогу static для генерации кэш-файлов и служебных JS.
STATIC_BASE_PATH = str(STATIC_SOURCE_ROOT)
database_engine = env('DATABASE_ENGINE', default='django.db.backends.sqlite3')
if database_engine == 'django.db.backends.sqlite3':
# Для SQLite принимаем только имя файла из env и кладем БД в PROJECT_ROOT/database.
sqlite_db_filename = Path(env('DATABASE_NAME', default='oknadria.sqlite3')).name
sqlite_db_path = PROJECT_ROOT / 'database' / sqlite_db_filename
DATABASES = {
'default': {
'ENGINE': "django.db.backends.mysql",
'HOST': MY_DATABASE_HOST_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_DATABASE_HOST_DEV2,
'PORT': MY_DATABASE_PORT_DEV, # Set to "" for default. Not used with sqlite3.
'NAME': MY_DATABASE_NAME_DEV, # Not used with sqlite3.
'USER': MY_DATABASE_USER_DEV, # Not used with sqlite3.
'PASSWORD': MY_DATABASE_PASSWORD_DEV, # Not used with sqlite3.
# 'OPTIONS': { 'autocommit': True, }
'ENGINE': 'django.db.backends.sqlite3',
'NAME': str(sqlite_db_path),
}
}
TOUCH_RELOAD = MY_TOUCH_RELOAD_DEV1 if socket.gethostname() == MY_HOST_HOME1 else MY_TOUCH_RELOAD_DEV2
else:
MEDIA_ROOT = MY_MEDIA_ROOT_PROD
# STATICFILES_DIRS = [MY_STATIC_ROOT_PROD1, ]
STATIC_ROOT = MY_STATIC_ROOT_PROD
SITEMAP_ROOT = MY_SITEMAP_ROOT_PROD
# путь к каталогу static (в эту переменную использовать для указания пути где будут делаться кэш-блоки для шаблонов)
STATIC_BASE_PATH = MY_STATIC_BASE_PATH_PROD
DATABASES = {
'default': {
'ENGINE': "django.db.backends.mysql",
'HOST': MY_DATABASE_HOST_PROD, # Set to "" for localhost. Not used with sqlite3.
'PORT': MY_DATABASE_PORT_PROD, # Set to "" for default. Not used with sqlite3.
'NAME': MY_DATABASE_NAME_PROD, # Not used with sqlite3.
'USER': MY_DATABASE_USER_PROD, # Not used with sqlite3.
'PASSWORD': MY_DATABASE_PASSWORD_PROD, # Not used with sqlite3.
# 'OPTIONS': { 'autocommit': True, }
'ENGINE': database_engine,
'HOST': env('DATABASE_HOST', default='localhost'),
'PORT': env('DATABASE_PORT', default='3306'),
'NAME': env('DATABASE_NAME', default=''),
'USER': env('DATABASE_USER', default=''),
'PASSWORD': env('DATABASE_PASSWORD', default=''),
}
}
TOUCH_RELOAD = MY_TOUCH_RELOAD_PROD
TOUCH_RELOAD = env('TOUCH_RELOAD', default='')
#########################################
# настройки для почтового сервера (они одинаковые для DEV и PROD)
EMAIL_HOST = MY_EMAIL_HOST_DEV
EMAIL_PORT = MY_EMAIL_PORT_DEV
EMAIL_HOST_USER = MY_EMAIL_HOST_USER_DEV
EMAIL_HOST_PASSWORD = MY_EMAIL_HOST_PASSWORD_DEV
SERVER_EMAIL = DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
EMAIL_USE_TLS = True
EMAIL_BACKEND = env(
'EMAIL_BACKEND',
default='django.core.mail.backends.smtp.EmailBackend',
)
EMAIL_HOST = env('EMAIL_HOST', default='localhost')
EMAIL_PORT = env.int('EMAIL_PORT', default=25)
EMAIL_HOST_USER = env('EMAIL_HOST_USER', default='')
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD', default='')
EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', default=True)
EMAIL_USE_SSL = env.bool('EMAIL_USE_SSL', default=False)
DEFAULT_FROM_EMAIL = env('DEFAULT_FROM_EMAIL', default=EMAIL_HOST_USER)
SERVER_EMAIL = env('SERVER_EMAIL', default=DEFAULT_FROM_EMAIL)
EMAIL_SUBJECT_PREFIX = 'OKNARDIA ERR: ' # префикс для оповещений об ошибках и необработанных исключениях
SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)
SESSION_COOKIE_SECURE = env.bool('SESSION_COOKIE_SECURE', default=False)
CSRF_COOKIE_SECURE = env.bool('CSRF_COOKIE_SECURE', default=False)
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
@@ -177,8 +215,8 @@ EMAIL_SUBJECT_PREFIX = 'OKNARDIA ERR: ' # префикс для оповещ
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# ключи для Google Captha
CAPTCHA_PUBLIC_KEY = MY_CAPTCHA_PUBLIC_KEY
CAPTCHA_PRIVATE_KEY = MY_CAPTCHA_PRIVATE_KEY
CAPTCHA_PUBLIC_KEY = env('CAPTCHA_PUBLIC_KEY', default='')
CAPTCHA_PRIVATE_KEY = env('CAPTCHA_PRIVATE_KEY', default='')
# количество коммерческих предложений во фреме отчета
OFFER_PER_FRAME = 5
@@ -272,4 +310,4 @@ CATALOG_SORTER_MAGIC_NUMBER_TIZER = 1
MAX_LEN_RING_LOG_BUFFER = 250 # МАКСИМАЛЬНЫЙ РАЗМЕР КОЛЬЦЕВОГО БУФЕРА
YANDEX_MAPS_API_KEY = MY_YANDEX_MAPS_API_KEY
YANDEX_MAPS_API_KEY = env('YANDEX_MAPS_API_KEY', default='')
+25 -20
View File
@@ -15,11 +15,11 @@
2. Добавьте URL-адрес в urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from django.urls import include, path, re_path
from django.conf.urls.static import static
from oknardia.settings import *
from web import views, autocomplete_addr, user_manager, blog, diagrams, report1, report2, catalog, prices, service
from web import views, autocomplete_addr, user_manager, blog, diagrams, report1, report2, catalog, prices, service, \
catalog_profiles, catalog_series, catalog_openings, catalog_companies
urlpatterns = [
path('admin/', admin.site.urls),
@@ -56,23 +56,26 @@ urlpatterns = [
re_path(r'^stat/series/geo[/*]$', diagrams.statistic_menu), # дубль для старых ссылок
re_path(r'^stat/rating[/*]$', report2.ratings),
re_path(r'^stat/rating/profiles_rank[/*]$', report2.profiles_rating),
# --- Каталог
# --- --- Каталог профилей
# --- КАТАЛОГ
re_path(r'^catalog[/*]$', catalog.catalog_root),
re_path(r'^catalog/profile[/*]$', catalog.catalog_profile),
# --- --- КАТАЛОГ ПРОФИЛЕЙ
re_path(r'^catalog/profile[/*]$', catalog_profiles.catalog_profile),
re_path(r'^catalog/profile/(?P<manufacture_id>\d+)-(?P<manufacture_name>\S*)'
r'/(?P<model_id>\d+)-(?P<model_name>\S*)[/*]$', catalog.catalog_profile_model),
r'/(?P<model_id>\d+)-(?P<model_name>\S*)[/*]$',
catalog_profiles.catalog_profile_model),
re_path(r'^catalog/profile/(?P<manufacture_id>\d+)-(?P<manufacture_name>\S*)[/*]$',
catalog.catalog_profile_manufacture),
catalog_profiles.catalog_profile_manufacture),
# --- --- Каталог серий типового строительства
re_path(r'^catalog/seria[/*]$', catalog.catalog_seria),
re_path(r'^catalog/seria/(?P<seria_name_translit>[^/]*)/all(?P<seria_id>\d+)[/*]$', catalog.catalog_seria_info),
re_path(r'^catalog/seria[/*]$', catalog_series.catalog_seria),
re_path(r'^catalog/seria/(?P<seria_name_translit>[^/]*)/all(?P<seria_id>\d+)[/*]$',
catalog_series.catalog_seria_info),
re_path(r'^seria_[^/]*/all(?P<seria_id>\d+)/\S*$', catalog.report_all_info_seria_redirect), # для старых ссылок
# --- --- Каталог стандартных проёмов и схем открывания длч типовых серий строительства
re_path(r'^catalog/standard_opening[/*]$', catalog.standard_opening),
re_path(r'^catalog/standard_opening[/*]$', catalog_openings.standard_opening),
# --- --- Каталог производителей окон
re_path(r'^catalog/company[/*]$', catalog.catalog_company),
re_path(r'^catalog/company/(?P<company_id>\d+)-(?P<company_name_slug>\S*)[/*]$', catalog.catalog_company_detail),
re_path(r'^catalog/company[/*]$', catalog_companies.catalog_company),
re_path(r'^catalog/company/(?P<company_id>\d+)-(?P<company_name_slug>\S*)[/*]$',
catalog_companies.catalog_company_detail),
# ЦЕНОВЫЕ ПРЕДЛОЖЕНИЯ
# --- Одиночное окно
re_path(r'^tsena-odnogo-okna/(?P<win_width_mm>\d+)x(?P<win_height_mm>\d+)mm/tip(?P<win_id>\d+)[/*]$',
@@ -96,16 +99,18 @@ urlpatterns = [
re_path(r'^service/tmp[/*]$', service.tmp),
# --- страничка "нет доступа"
re_path(r'^service/not-denice[/*]$', service.not_denice),
# --- создание файлов sitemap.xml
re_path(r'^service/make_sitemaps[/*]$', service.make_site_maps),
re_path(r'^service/make_rating[/*]$', service.make_rating),
]
if DEBUG:
# ___ ____ _ _____ _ _ _____ _
# | | | | \ ___| |_ _ _ ___ |_ _|___ ___| | |_ ___ ___ | _ |___ ___ ___| |
# |_ | | | | -_| . | | | . | | | | . | . | | . | .'| _| | __| .'| | -_| |
# |_| |____/|___|___|___|_ | |_| |___|___|_|___|__,|_| |__| |__,|_|_|___|_|
# |___|
urlpatterns = [path('__debug__/', include('debug_toolbar.urls')), *urlpatterns]
# Медиа-файлы
urlpatterns += static(MEDIA_URL, document_root=MEDIA_ROOT)
# ___ ____ _ _____ _ _ _____ _
# | | | | \ ___| |_ _ _ ___ |_ _|___ ___| | |_ ___ ___ | _ |___ ___ ___| |
# |_ | | | | -_| . | | | . | | | | . | . | | . | .'| _| | __| .'| | -_| |
# |_| |____/|___|___|___|_ | |_| |___|___|_|___|__,|_| |__| |__,|_|_|___|_|
# |___|
+5 -1
View File
@@ -17,6 +17,10 @@
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>{% block Title %}{% endblock %} : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link rel="icon" href="https://oknardia.ru/favicon.svg" type="image/svg+xml ">
<link rel="icon" href="https://oknardia.ru/favicon.png" type="image/png">
<link rel="icon" href="https://oknardia.ru/favicon.gif" type="image/gif">
<link rel="icon" href="https://oknardia.ru/favicon.ico" type="image/x-icon">
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" type="text/css" />{# <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />#}
<link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet" type="text/css" />{# <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />#}
<link href="{% static 'css/oknardia1.css' %}" rel="stylesheet" type="text/css" />{% block Top_CSS1 %}{% endblock %}{% block Top_CSS2 %}{% endblock %}{% block Top_CSS3 %}{% endblock %}
@@ -81,7 +85,7 @@
{# <!-- Yandex.Metrika counter --> #}(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>{# <!--/LiveInternet--> #}
</span>
<small>© oknardia.ru, 2015-{% now "Y" %}. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: {{ ticks }}{{ TAU }} сек---></small>
<small>© oknardia.ru, 2015-{% now "Y" %}. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: {{ ticks }}{{ TAU }} сек---> {{ ticks }}{{ TAU }} сек </small>
</div>
</div>{% endblock %}
{# ######################################## Нижнее меню-футер КОНЕЦ ######################################## #}
@@ -5,13 +5,9 @@
{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %}
{% block Description %}Каталог оконных профилей{% endblock %}
{% block Description %}Подберите оконный профиль под свои требования: в каталоге «Окнардии» собраны производители, марки и ключевые характеристики.{% endblock %}
{% block Keywords %}каталог оконных профилей, каталог производителей оконных профилей, каталог профилей, оконные профили, oknardia, окнардия {{ META_KEYWORDS|default:"" }} {% endblock %}
{% block Date4Meta %}{{ CATALOG_LAST_UPDATE|date:"c" }}{% endblock %}
{% block Last4Meta %}{{ CATALOG_LAST_UPDATE|date:"c" }}{% endblock %}
{% block Keywords %}оконные профили, каталог профилей, сравнение профилей, производители оконных профилей, характеристики оконных профилей, oknardia {{ META_KEYWORDS|default:"" }} {% endblock %}
{% block Author4Meta %}: Каталог{% endblock %}
@@ -27,7 +23,7 @@
<li>Оконные профили</li>
</ol>
<h1>Каталог оконных профилей</h1>
<p>Узнать о&nbsp;производителях, познакомиться с&nbsp;детальными характеристики и&nbsp;описаниями оконных профилей можно кликнув по&nbsp;ссылкам. Сейчас в&nbsp;каталоге &laquo;Окнардии&raquo; представлено {{ CATALOG_MANUFACT_NUM_W }} профилей ({{ CATALOG_PROFILE_NUM }} в&nbsp;базе). Последнее обновление {{ CATALOG_LAST_UPDATE_W }}.</p>
<p>Узнать о&nbsp;производителях, познакомиться с&nbsp;детальными характеристики и&nbsp;описаниями оконных профилей можно кликнув по&nbsp;ссылкам. Сейчас в&nbsp;каталоге &laquo;Окнардии&raquo; представлено {{ CATALOG_MANUFACT_NUM_W }} профилей ({{ CATALOG_PROFILE_NUM }} в&nbsp;базе).</p>
</div>
</div>{# <!--- Хлебные крошки: КОНЕЦ ---> #}
<div class="row">
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,368 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:31:05.856942+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:31:05.857034+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:31:05.857082+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии ПД-4: детальная информация" />
<meta name="keywords" content=" ПД-4, серия ПД-4, проект ПД-4, года постройки зданий серии ПД-4, размеры окон в домах серии ПД-4, оконные проемы зданий серии ПД-4, дома серии ПД-4 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии ПД-4 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия ПД-4</li>
</ol>
<h1>СЕРИЯ ПД-4</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии ПД-4: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/116x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:134px;min-width:13ex;">
<nobr>1160×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ<br />
<a href="/tsena-odnogo-okna/1160x1420mm/tip2">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:77px;min-width:13ex;">
<nobr>670×2160&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/116x142H216W-(G_)(L).png" alt="Окно двустворчатое для серии ПД-4. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии ПД-4. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:134px;min-width:13ex;">
<nobr>1160×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Окно двустворчатое для серии ПД-4<br />
<a href="/tsena-odnogo-okna/1160x1420mm/tip45">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:170px;min-width:13ex;">
<nobr>1470×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap4">
<div><img src="/static/img/_flap.cfg/206x142H216W-(G)(G)(L).png" alt="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:238px;min-width:13ex;">
<nobr>2060×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4<br />
<a href="/tsena-odnogo-okna/2060x1420mm/tip10">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии ПД-4</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия ПД-4: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1961",4,"color: #99a899"],
["1962",11,"color: #99c499"],
["1963",6,"color: #99b099"],
["1964",1,"color: #999c99"],
["1995",1,"color: #999c99"],
["1996",6,"color: #99b099"],
["1997",13,"color: #99cc99"],
["1998",6,"color: #99b099"],
["1999",11,"color: #99c499"],
["2000",9,"color: #99bc99"],
["2001",8,"color: #99b899"],
["2002",6,"color: #99b099"],
["2003",6,"color: #99b099"],
["2004",5,"color: #99ac99"],
["2005",1,"color: #999c99"],
["2006",2,"color: #99a099"],
["2008",2,"color: #99a099"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии ПД-4 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии ПД-4 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.564053,37.570941],[55.562907,37.570366],[55.563656,37.569306],[55.662364,37.779098],[55.748812,37.985073],[55.663486,37.765363],[55.490585,37.297512],[55.663888,37.769397],[55.633760,37.739600],[55.632916,37.738575],[55.632987,37.769558],[55.655437,37.764519],[55.863576,37.432025],[55.864818,37.431154],[55.567667,37.570923],[55.568110,37.571606],[55.568089,37.569701],[55.568354,37.568192],[55.568777,37.568821],[55.568782,37.566880],[55.569011,37.565353],[55.569494,37.566126],[55.569443,37.564168],[55.858074,37.568120],[55.739448,37.853048],[55.739868,37.853874],[55.550723,37.556208],[55.551599,37.556622],[55.550611,37.558167],[55.550101,37.558059],[55.550244,37.559173],[55.550789,37.559056],[55.546190,37.557780],[55.546908,37.558751],[55.548294,37.559451],[55.548660,37.560224],[55.545258,37.557879],[55.546083,37.558805],[55.546699,37.559460],[55.546842,37.560251],[55.736650,37.846760],[55.736883,37.847927],[55.735748,37.847119],[55.843222,37.386903],[55.842464,37.387622],[55.854704,37.360897],[55.855441,37.359504],[55.855896,37.358462],[55.837702,37.390532],[55.838668,37.390415],[55.750707,37.992790],[55.747819,37.988370],[55.750707,37.991775],[55.750727,37.989807],[55.750758,37.988783],[55.750778,37.987777],[55.956965,38.063846],[55.958321,38.062122],[55.922696,37.722361],[55.662699,37.766306],[55.840502,37.527399],[55.840442,37.528424],[55.654625,37.606137],[55.653898,37.606155],[55.840629,37.529852],[55.633932,37.747253],[55.631966,37.768175],[55.863379,37.430714],[55.857235,37.568201],[55.548044,37.560871],[55.854082,37.362136],[59.881525,30.454595],[59.883905,30.487096],[59.882049,30.483602],[59.881313,30.482003],[59.880600,30.480413],[59.879931,30.478858],[59.874110,30.476658],[59.880911,30.469776],[59.878130,30.464234],[59.881214,30.461710],[59.879371,30.463425],[59.881074,30.462859],[59.879827,30.464198],[59.879191,30.464333],[59.879647,30.465240],[59.881498,30.464620],[59.881850,30.465249],[59.879827,30.466273],[59.880017,30.466902],[59.880419,30.467728],[59.880433,30.468645],[59.881728,30.477421],[55.745336,38.023171],[55.746015,38.021311],[55.428066,37.561059],[55.923473,37.724086],[55.924204,37.722397]];
let forURL = [386,388,10894,20193,71407,982,2134,12210,12704,12750,12833,12869,13603,13621,14936,14937,14938,14939,14940,14941,14946,14947,14948,15636,22141,22148,26758,26760,26761,26762,26763,26764,26767,26768,26769,26771,26772,26773,26774,26775,27668,27669,27724,32273,32274,32291,32293,32297,32302,32303,71401,71429,71436,71471,71474,71476,80428,80430,97640,983,20787,20788,1110,1111,9538,12718,12830,13625,15635,26770,32285,37770,39797,39801,39810,39815,39819,39829,40580,51926,51929,51930,51931,51934,51936,51937,51939,51941,51942,51943,51948,51953,51978,71533,71542,77732,97641,97647];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии ПД-4</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии ПД-4 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии ПД-4</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>16024</strong> квартир.</li>
<li>Проживает <strong>14641</strong> семей <small>(<strong>69926</strong> человек)</small>.</li>
<li><strong>825653.9 м²</strong> жилых помещений.</li>
<li><strong>22532.1 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>28434.2 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии ПД-4&nbsp;<strong>30.00%</strong>. Минимальный&nbsp;<strong>1.40%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;ПД-4, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,346 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:30:27.483379+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:27.483423+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:30:27.483448+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии К-7: детальная информация" />
<meta name="keywords" content=" К-7, серия К-7, проект К-7, года постройки зданий серии К-7, размеры окон в домах серии К-7, оконные проемы зданий серии К-7, дома серии К-7 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии К-7 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия К-7</li>
</ol>
<h1>СЕРИЯ К-7</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии К-7: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/132x153H153W-(G)(L_).png" alt="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:215px;min-width:13ex;">
<nobr>1320×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9<br />
<a href="/tsena-odnogo-okna/1320x1530mm/tip23">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/188x153H153W-(G_)(G_)(L).png" alt="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:307px;min-width:13ex;">
<nobr>1880×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Окно трёхстворчатое для серии К9 и 1-515/9Ш<br />
<a href="/tsena-odnogo-okna/1880x1530mm/tip38">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии К-7</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия К-7: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1926",1,"color: #999a99"],
["1929",3,"color: #999c99"],
["1959",7,"color: #99a099"],
["1960",6,"color: #999f99"],
["1961",25,"color: #99b399"],
["1962",23,"color: #99b199"],
["1963",48,"color: #99cc99"],
["1964",36,"color: #99bf99"],
["1965",10,"color: #99a399"],
["1966",18,"color: #99ac99"],
["1967",2,"color: #999b99"],
["1976",1,"color: #999a99"],
["1978",1,"color: #999a99"],
["1984",1,"color: #999a99"],
["1989",1,"color: #999a99"],
["1991",1,"color: #999a99"],
["1996",1,"color: #999a99"],
["1998",1,"color: #999a99"],
["2000",1,"color: #999a99"],
["2003",1,"color: #999a99"],
["2004",1,"color: #999a99"],
["2010",11,"color: #99a499"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии К-7 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии К-7 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.862510,37.560440],[55.861646,37.560170],[55.861863,37.558885],[55.863510,37.559371],[55.872774,37.549642],[55.858518,37.561293],[55.859261,37.561329],[55.860064,37.561419],[55.860009,37.560655],[55.859797,37.559936],[55.851551,37.432007],[55.852435,37.431989],[55.769393,37.475243],[55.769524,37.471560],[55.769524,37.471560],[55.774087,37.462918],[55.775358,37.460951],[55.775798,37.460421],[55.862853,37.558400],[55.863181,37.558885],[55.673610,37.497575],[55.672661,37.495887],[55.788672,37.785557],[55.788692,37.787336],[55.668965,37.510987],[55.668894,37.509514],[55.666096,37.509846],[55.666096,37.509119],[55.666091,37.508409],[55.774482,37.474426],[55.774482,37.474426],[55.774482,37.474426],[55.775322,37.471255],[55.774862,37.471767],[55.774958,37.471102],[55.775039,37.470428],[55.776112,37.462676],[55.776208,37.462002],[55.776310,37.461337],[55.871976,37.641459],[55.871471,37.636176],[55.872062,37.635602],[55.871334,37.634676],[55.871991,37.634865],[55.871920,37.634119],[55.871198,37.633185],[55.871854,37.633365],[55.872087,37.642950],[55.885186,37.656407],[55.885635,37.656047],[55.886347,37.655481],[55.886796,37.655140],[55.884731,37.656766],[55.855138,37.645294],[55.854401,37.644710],[55.855841,37.644980],[55.856326,37.642698],[55.855542,37.642150],[55.855108,37.639635],[55.855108,37.639635],[55.856801,37.640390],[55.856801,37.640390],[55.856331,37.639159],[55.857043,37.638692],[55.880960,37.644513],[55.882707,37.648349],[55.882141,37.649274],[55.883232,37.650020],[55.883035,37.651717],[55.874471,37.627813],[55.874294,37.625837],[55.874865,37.626493],[55.875971,37.626852],[55.875334,37.623465],[55.875031,37.624921],[55.875890,37.625424],[55.874758,37.623061],[55.871723,37.631963],[55.871784,37.632619],[55.878405,37.620061],[55.473265,37.539006],[55.343200,37.638458],[55.343200,37.638458],[55.343200,37.638458],[55.860630,37.473114],[55.865273,37.471372],[55.863121,37.425477],[55.857700,37.425656],[55.857745,37.424147],[55.723100,37.567590],[55.723962,37.568408],[55.723775,37.569009],[55.723212,37.568713],[55.867834,37.673169],[55.867177,37.673268],[55.865945,37.678505],[55.867692,37.674714],[55.822428,37.587290],[55.821897,37.584990],[55.822620,37.584730],[55.823312,37.584182],[55.878243,37.633167],[55.878758,37.628110],[55.878066,37.623232],[55.878152,37.622432],[55.879329,37.621669],[55.878233,37.621651],[55.878314,37.620851],[55.879601,37.639653],[55.772456,37.471821],[55.772548,37.471165],[55.772968,37.473420],[55.773054,37.472791],[55.773570,37.474022],[55.773667,37.473366],[55.773763,37.472710],[55.773763,37.472710],[55.770704,37.470734],[55.770487,37.472827],[55.770704,37.473959],[55.771935,37.471120],[55.771403,37.470877],[55.660800,37.519207],[55.661978,37.514733],[55.661978,37.514733],[55.661978,37.514733],[55.661978,37.514733],[55.661237,37.513422],[55.660937,37.513853],[55.660892,37.514661],[55.875319,37.634407],[55.875511,37.631999],[55.875935,37.635188],[55.882853,37.641144],[55.872127,37.636347],[55.873198,37.635709],[55.874395,37.634766],[55.861444,37.555220],[55.861752,37.556469],[55.854224,37.650091],[55.810840,37.569207],[55.853001,37.422970],[55.853087,37.423761],[55.859499,37.474974],[55.856962,37.477067],[55.858306,37.476878],[55.857068,37.479582],[55.857639,37.480139],[55.859221,37.479573],[55.858488,37.480489],[55.857750,37.481343],[55.821042,37.584586],[55.820329,37.587191],[55.821138,37.585251],[55.821269,37.585880],[55.820430,37.583805],[55.800701,37.727302],[55.796840,37.615345],[55.794836,37.615470],[55.821295,37.582556],[55.821457,37.583230],[55.822068,37.582484],[55.822473,37.580643],[55.822625,37.581298],[55.822776,37.581963],[55.858473,37.559371],[55.859398,37.558472],[55.859600,37.559200],[55.859539,37.557430],[55.859539,37.557430],[55.859539,37.557430],[55.476664,37.295131],[55.476490,37.296209],[55.481087,37.300117],[55.475888,37.295086],[55.672184,37.495033],[55.671712,37.494180],[55.768203,37.711347],[55.870662,37.464625],[55.872157,37.463610],[55.866031,37.472135],[55.858513,37.475010],[55.893243,37.539940],[55.651821,37.553765],[55.805832,37.817492],[55.808245,37.816603],[55.861595,37.555831],[55.673016,37.754556],[55.804941,37.614832],[55.719794,37.802814],[55.717492,37.809614],[59.737400,30.462752],[59.737686,30.462123],[59.736090,30.464405],[59.735813,30.465042],[59.736806,30.462859],[59.737074,30.462231],[59.736108,30.465608],[59.733273,30.466614],[59.734167,30.468070],[59.733273,30.466614],[59.734167,30.468070]];
let forURL = [172,173,174,175,217,218,251,255,256,257,1521,1522,2819,2821,2823,2828,2833,2835,3517,3518,6168,6173,6531,6533,6738,6739,6772,6775,6778,6968,6969,6970,6973,6974,6975,6976,6987,6988,6989,8139,8151,8152,8159,8160,8161,8169,8170,8180,8300,8302,8305,8307,8316,9162,9163,9164,9165,9166,9168,9169,9170,9171,9172,9173,9727,9740,9743,9747,9755,9856,9860,9865,9866,9867,9869,9871,9873,9877,9878,9881,9937,10233,10234,10236,12173,12195,13600,14497,14503,15383,15392,15393,15394,20459,20460,20489,20490,20621,20622,20624,20626,20967,20974,20986,20987,20988,20989,20990,20994,21566,21567,21574,21575,21581,21582,21583,21584,21606,21625,21634,21640,21641,21961,22691,22692,22693,22694,22704,22710,22712,24914,24916,24920,24938,24948,24967,24971,26531,26538,26881,28275,28491,28492,28961,28962,28968,28982,28986,28988,28989,28990,29242,29243,29245,29247,29256,29418,30266,30291,30912,30913,30915,30918,30919,30920,31583,31584,31585,31586,31587,31588,2154,2155,2168,2174,6180,6185,19284,7965,7968,12166,28959,15424,22687,23546,23563,26537,27593,30279,29517,29525,45464,45465,45499,45500,45502,45503,45505,45535,45538,45555,45558];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии К-7</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии К-7 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии К-7</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>19354</strong> квартир.</li>
<li>Проживает <strong>16839</strong> семей <small>(<strong>82948</strong> человек)</small>.</li>
<li><strong>539518.2 м²</strong> жилых помещений.</li>
<li><strong>93304.8 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>27709.9 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии К-7&nbsp;<strong>69.00%</strong>. Минимальный&nbsp;<strong>4.80%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;К-7, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,359 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:28:02.157690+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:28:02.157739+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:28:02.157763+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии 1-335: детальная информация" />
<meta name="keywords" content=" 1-335, серия 1-335, проект 1-335, года постройки зданий серии 1-335, размеры окон в домах серии 1-335, оконные проемы зданий серии 1-335, дома серии 1-335 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии 1-335 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия 1-335</li>
</ol>
<h1>СЕРИЯ 1-335</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"><p>Пятиэтажка 1&ndash;335 проектировалась Ленинградским Отделением Горстройпроекта (архитекторы Баныкин&nbsp;Б. Н., Артемьева И. Б. и&nbsp;Смирнова Л. А.) и&nbsp;стала одним из&nbsp;первых зданий &laquo;полукаркасной&raquo; схемы (неполный каркас и&nbsp;навесные панели). Возводилась по&nbsp;всей территории СССР с&nbsp;1956 года. Последние здания серии сданы в&nbsp;эксплуатацию в&nbsp;1968 году.</p>
<p>Проект 1&ndash;335 так и&nbsp;не&nbsp;получил дальнейшей модернизации, <nobr>из-за</nobr> ряда недостатков. Так, профильные навесные бетонные панели толщиной 30&nbsp;см.&nbsp;приводили к&nbsp;теплопотерям, и&nbsp;замена на&nbsp;керамзитбетонные (40&nbsp;см.) для регионов с&nbsp;суровым климатом не&nbsp;спасало. Внешняя облицовка утепляющими материалами увеличивала стоимость и&nbsp;эксплуатационные расходы, потому 1&ndash;335 возводились только в&nbsp;Ленинграде, где климат мягче.</p>
<p>Внешний вид 1&ndash;335 не&nbsp;сильно отличается от&nbsp;других панельных зданий того периода. Серию можно узнать по&nbsp;боковому фасаду: без балконов, две панели без окон в&nbsp;центре или по&nbsp;краям. Как и&nbsp;у&nbsp;многих &laquo;хрущёвок&raquo;, серия 1&ndash;335 с&nbsp;железной четырёхскатной крышей (поздние модификации строились с&nbsp;плоской крышей без чердаков), секции без лифта (по&nbsp;четыре квартиры: 1-, 2- и&nbsp;<nobr>3-комнатные</nobr>), потолки 255&nbsp;см., санузер совмещенный.</p>
<p>Оконные проемы серии 1&ndash;335 на&nbsp;10&ndash;15&nbsp;см шире чем у&nbsp;других &laquo;хрущёвок&raquo;, но&nbsp;максимум пять этажей подразумевают низкие ветровые нагрузки. Это означает, что при замене окон использование усиленных профилей не&nbsp;обязательно. Кроме того, нецелесообразно использование стеклопакетов с&nbsp;заполнением инертным газом и&nbsp;высоким сопротивлением теплопередаче&nbsp;&mdash; утечки тепла через панели сведут на&nbsp;нет их&nbsp;преимущество. Благодаря хорошей вытяжной вентиляции здания можно сэкономить на&nbsp;встраиваемых в&nbsp;окна клапанах <nobr>климат-контроля</nobr>.</p></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии 1-335: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/126x138H207WN(G)(L).png" alt="Окно двустворчатое «Хрущевка» на балкон (серии 1-335). Размер 1260x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое «Хрущевка» на балкон (серии 1-335). Размер 1260x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:152px;min-width:13ex;">
<nobr>1260×1380&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно двустворчатое «Хрущевка» на балкон (серии 1-335)<br />
<a href="/tsena-odnogo-okna/1260x1380mm/tip49">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/068x207H207D-(L).png" alt="Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5). Размер 680x2070 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5). Размер 680x2070 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:82px;min-width:13ex;">
<nobr>680×2070&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Дверь на балкон «Хрущевка» (серии 1-335, 507, 510, 511 и 515/5)<br />
<a href="/tsena-odnogo-okna/680x2070mm/tip40">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/128x138H207W-(G)(L).png" alt="Окно двустворчатое «Хрущевка» (серии 1-335). Размер 1280x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое «Хрущевка» (серии 1-335). Размер 1280x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:154px;min-width:13ex;">
<nobr>1280×1380&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Окно двустворчатое «Хрущевка» (серии 1-335)<br />
<a href="/tsena-odnogo-okna/1280x1380mm/tip48">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/194x138H207W-(G)(L)(L).png" alt="Окно трёхстворчатое «Хрущевка» (серии 1-335). Размер 1940x1380 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое «Хрущевка» (серии 1-335). Размер 1940x1380 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:234px;min-width:13ex;">
<nobr>1940×1380&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно трёхстворчатое «Хрущевка» (серии 1-335)<br />
<a href="/tsena-odnogo-okna/1940x1380mm/tip47">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1-335</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия 1-335: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1956",1,"color: #999a99"],
["1957",1,"color: #999a99"],
["1959",11,"color: #99a499"],
["1960",25,"color: #99b299"],
["1961",50,"color: #99cc99"],
["1962",37,"color: #99be99"],
["1963",7,"color: #99a099"],
["1964",29,"color: #99b699"],
["1965",18,"color: #99ab99"],
["1966",20,"color: #99ad99"],
["1967",18,"color: #99ab99"],
["1968",1,"color: #999a99"],
["1969",1,"color: #999a99"],
["2000",2,"color: #999b99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии 1-335 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии 1-335 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.797847,37.813495],[55.797857,37.814241],[55.797908,37.818579],[55.797898,37.817825],[55.797888,37.817061],[55.802568,37.813504],[55.802077,37.812534],[55.802103,37.814483],[55.788960,37.786366],[55.819772,37.623492],[55.819793,37.622792],[55.732342,37.425171],[55.787118,37.454672],[55.869617,37.673969],[55.799456,37.812677],[55.799467,37.813441],[55.799477,37.814178],[55.798667,37.814627],[55.798677,37.815310],[55.799527,37.818508],[55.799507,37.817762],[55.799502,37.816998],[55.798692,37.816639],[55.798682,37.815974],[55.796618,37.482897],[60.009534,30.415527],[60.009521,30.417270],[59.988005,30.419004],[59.987839,30.417926],[60.011163,30.432703],[55.802614,37.817430],[55.802143,37.818364],[55.682295,37.745268],[55.874466,37.712605],[60.094954,29.975173],[60.101176,29.978479],[59.928690,30.414494],[59.972613,30.430331],[60.016348,30.369965],[59.922864,30.422193],[60.019298,30.409329],[60.019451,30.408700],[60.019536,30.411467],[60.019212,30.411997],[60.019068,30.412662],[59.925173,30.422687],[59.924050,30.422408],[59.924055,30.423010],[59.922747,30.423298],[59.955512,30.436647],[59.955611,30.435245],[59.955687,30.433637],[59.955773,30.432110],[59.955863,30.430502],[59.966174,30.434886],[59.969912,30.434203],[59.972830,30.434428],[59.972199,30.432640],[59.972186,30.427933],[59.920997,30.423801],[59.921205,30.424474],[59.927017,30.429155],[59.927640,30.431661],[59.928735,30.430251],[60.009215,30.433476],[60.009926,30.432047],[60.017306,30.411871],[60.013564,30.406984],[59.967399,30.433242],[59.969299,30.433071],[59.925398,30.417009],[59.926792,30.418725],[59.926512,30.420396],[59.958363,30.424178],[59.957890,30.426729],[59.957751,30.428247],[59.958647,30.429424],[59.958440,30.430790],[59.958850,30.413210],[55.591447,37.642060],[55.590562,37.642411],[55.681696,37.571857],[55.681427,37.572585],[55.681189,37.573321],[55.674529,37.578594],[55.674184,37.578235],[55.673864,37.577912],[59.932180,30.414656],[59.930304,30.413254],[59.929849,30.414692],[59.930660,30.415105],[59.929366,30.415033],[59.929227,30.417045],[59.929673,30.416560],[59.929799,30.421160],[59.930178,30.423369],[59.930944,30.427942],[59.928181,30.414288],[59.927860,30.415105],[59.927860,30.415105],[59.926990,30.416174],[59.926990,30.416174],[59.925642,30.415851],[59.924339,30.417405],[59.923667,30.418312],[59.922990,30.419273],[59.923410,30.420495],[59.921913,30.420755],[59.922305,30.421986],[59.921971,30.423001],[59.920830,30.422292],[59.932017,30.415348],[59.928519,30.421043],[59.927915,30.420513],[59.930886,30.416183],[59.928009,30.421654],[59.928009,30.421654],[59.927671,30.422004],[59.929344,30.417611],[59.927220,30.421276],[59.927125,30.422579],[59.928627,30.418447],[59.928095,30.418357],[59.926774,30.422983],[59.928460,30.416965],[59.926142,30.422633],[59.927482,30.417764],[59.923775,30.425867],[59.927243,30.419291],[59.927071,30.420252],[59.925777,30.421806],[59.924474,30.423549],[59.923595,30.423612],[59.923707,30.424618],[59.922959,30.423926],[59.922373,30.424295],[59.922900,30.425732],[59.922048,30.426882],[59.982658,30.411673],[59.986596,30.422786],[59.920636,30.423387],[59.921412,30.425112],[59.921813,30.425525],[59.921615,30.426280],[59.923423,30.428131],[59.925196,30.428436],[59.927044,30.427699],[59.926684,30.430421],[59.927247,30.430565],[59.927901,30.428876],[59.927906,30.430340],[59.928573,30.431032],[59.932414,30.322022],[59.932085,30.321725],[59.931544,30.321105],[59.931314,30.320512],[59.933681,30.323207],[59.933510,30.323055],[59.932748,30.322336],[59.924957,30.417162],[59.925087,30.418195],[59.925002,30.420719],[59.926224,30.416857],[59.925547,30.420387],[59.895615,30.422094],[59.895226,30.421016],[59.894450,30.420782],[59.894780,30.419641],[59.973320,30.425301],[59.972181,30.424061],[59.973325,30.428768],[60.017004,30.375435],[60.016780,30.376738],[60.013227,30.402645],[59.965660,30.401774],[60.015597,30.369713],[60.014522,30.369686],[60.014576,30.370477],[60.014248,30.374115],[60.014113,30.374869],[60.013353,30.374762],[59.964332,30.435326],[59.971105,30.433044],[59.974923,30.404226],[59.972839,30.422283],[60.007888,30.431284],[60.009215,30.433476],[60.012210,30.415240],[59.968142,30.435155],[59.958341,30.426020],[59.958602,30.430134],[59.973284,30.432487],[60.016492,30.394228],[60.013771,30.402250],[60.012534,30.405376],[60.016447,30.372911],[59.930403,30.412554],[60.012669,30.403786],[60.010659,30.412644],[60.010717,30.413488],[60.009193,30.419839],[60.009004,30.420477],[60.014009,30.375624],[59.973766,30.404837],[59.973910,30.403687],[59.972762,30.403723],[59.973136,30.404155],[59.973239,30.405655],[59.973816,30.407532],[60.006984,30.429173],[60.007047,30.431544],[60.007663,30.429451],[60.016901,30.373163],[59.955647,30.434464],[59.955818,30.431302],[59.972019,30.406688],[59.984283,30.402600],[59.983671,30.406625],[59.954119,30.433332],[59.954092,30.434086],[55.032480,82.904197]];
let forURL = [500,501,506,507,508,1186,1187,1188,6532,10981,10982,15807,15993,19036,23453,23454,23455,23456,23457,23512,23513,23514,23515,23516,25685,42831,42833,47423,47428,53621,1195,1196,5964,19285,36627,36648,40749,42235,42826,43196,43811,43812,43815,43817,43818,44775,44777,44778,44782,44947,44948,44951,44955,44959,44998,45003,45008,45010,47599,48689,48690,48705,48713,48715,53618,53620,54364,54392,54485,54487,54693,54699,54700,56026,56029,56032,56033,56036,56047,9494,9495,17262,17263,17264,18444,18445,18446,38621,40744,40746,40750,40751,40754,40756,40760,40763,40770,43156,43157,43158,43163,43165,43176,43178,43184,43191,43192,43194,43195,43197,43203,44740,44743,44745,44747,44748,44749,44750,44751,44753,44755,44757,44758,44760,44761,44762,44765,44768,44770,44772,44774,44776,44779,44780,44781,44783,44784,44785,46886,47434,48688,48691,48692,48693,48696,48700,48702,48709,48710,48711,48712,48714,49929,49930,49931,49932,49933,49934,49935,54687,54690,54694,54696,54697,40667,40669,40672,40675,42229,51740,42233,42798,42808,42814,43407,44361,44419,44420,44422,44423,44424,44996,45006,50273,51741,53614,53619,54381,54491,56027,56034,42239,42807,42813,42818,42871,43146,42815,42828,42829,42843,42844,44417,46392,46395,46396,46397,46398,50266,53610,53612,53613,42882,44950,44957,46399,46880,46883,47193,47194,58339];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии 1-335</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии 1-335 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии 1-335</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>19742</strong> квартир.</li>
<li>Проживает <strong>20521</strong> семей <small>(<strong>98798</strong> человек)</small>.</li>
<li><strong>904827.7 м²</strong> жилых помещений.</li>
<li><strong>6470.2 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>31829.0 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии 1-335&nbsp;<strong>70.00%</strong>. Минимальный&nbsp;<strong>6.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;1-335, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,387 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:31:02.370699+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:31:02.370777+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:31:02.370817+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии П-55: детальная информация" />
<meta name="keywords" content=" П-55, серия П-55, проект П-55, года постройки зданий серии П-55, размеры окон в домах серии П-55, оконные проемы зданий серии П-55, дома серии П-55 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии П-55 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия П-55</li>
</ol>
<h1>СЕРИЯ П-55</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"><p>Типовой проект жилой серии П-55 <nobr>и П-55М</nobr> проектировался в&nbsp;конце 1970-х как шумозащитный. Размещение домов предполагалось вдоль больших автомагистралей или на&nbsp;границе промышленных зон. Возведением серии занимались в&nbsp;основном ДСК-4 и&nbsp;АО «Моспромстроиматериалов». Повышенная шумоизоляция достигалась благодаря использованию специальных трёхслойных керамзитбетонных панелей и&nbsp;оригинальной планировкой, благодаря которой на&nbsp;неблагоприятную сторону выходили главным образом нежилые помещения. Кроме того, внешний фасад имел минимальное число балконов, таким образом уменьшая проникновение пыли в&nbsp;жилые комнаты.</p>
<p>Внешний фасад серии П-55 и&nbsp;П-55М выстраивался уступами, что значительной степени отражало шум. Сверх того, дома серии часто строили в&nbsp;виде Г- и&nbsp;П-образных конструкций и&nbsp;снабжали арками, что повышало защиту дворов. Но&nbsp;даже рядные&nbsp;— обычно двух- и&nbsp;трехсекционные блок-дома&nbsp;— в&nbsp;силу большой высотности<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>10−14 этажей) являлись достаточным препятствием для проникновения шума и&nbsp;пыли в&nbsp;дворы, в&nbsp;стороны которых выходили окна жилых комнат и&nbsp;большое число балконов.</p>
<p>Являясь поздними<span style="margin-right:0.44em;"> </span><span style="margin-left:-0.44em;">«</span>брежневскими» серией панельного строительства, в&nbsp;П-55 значительное внимание уделялось удобству: в&nbsp;подъездах расположено по&nbsp;два пассажирских лифта, большинство квартир с&nbsp;несколькими балконами, много трёх- и&nbsp;четырёхкомнатных квартир. Кроме того, проект П-55 отличает более высокие чем у&nbsp;предыдущих серий <nobr>потолки<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>2 м 65 см)</nobr> и&nbsp;увеличенные размеры ванной и&nbsp;туалетной комнаты. Улучшенная серия П-55М ещё более комфортна: вторые санузлы в&nbsp;трёх- и&nbsp;четырёхкомнатных квартирах; входной блок подъезда и&nbsp;лифт адаптирован для инвалидов-колясочников.</p>
<strong><p>В&nbsp;силу расположенности зданий серий П-55 вдоль шумных магистралей и&nbsp;промышленных зон, замена окон в&nbsp;них предполагает установку более качественных, дорогих, но&nbsp;и&nbsp;более защищённых конструкций<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>особенно для внешнего фасада). В&nbsp;первую очередь следует отдавать предпочтение предложениям с&nbsp;повышенной шумоизоляцией:</p>
<ul><li>двухкамерные стеклопакеты высокой звукоизоляции<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>32 дБ&nbsp;и&nbsp;более) с&nbsp;несимметричными камерами или заполненные инертным газом;</li>
<li>пятикамерные<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>и&nbsp;выше) профили с&nbsp;шумовой защитой на&nbsp;ниже 3-го класса<span style="margin-right:0.3em;"> </span><span style="margin-left:-0.3em;">(</span>коэффициент звукоизоляции от&nbsp;35 дБ)</li>
<li>три и&nbsp;более контура уплотнения.</li></ul></strong></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии П-55: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/087x142H216WN(G).png" alt="Окно на балкон для серии П-30, П-46 и П-55. Размер 870x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно на балкон для серии П-30, П-46 и П-55. Размер 870x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:100px;min-width:13ex;">
<nobr>870×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно на балкон для серии П-30, П-46 и П-55<br />
<a href="/tsena-odnogo-okna/870x1420mm/tip12">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:77px;min-width:13ex;">
<nobr>670×2160&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:170px;min-width:13ex;">
<nobr>1470×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/206x142H216W-(G)(G)(L).png" alt="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4. Размер 2060x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:238px;min-width:13ex;">
<nobr>2060×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно трёхстворчатое для серии КОПЭ, П-55 и ПД-4<br />
<a href="/tsena-odnogo-okna/2060x1420mm/tip10">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии П-55</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия П-55: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1911",1,"color: #999b99"],
["1926",1,"color: #999b99"],
["1938",1,"color: #999b99"],
["1958",1,"color: #999b99"],
["1959",1,"color: #999b99"],
["1960",1,"color: #999b99"],
["1961",1,"color: #999b99"],
["1965",1,"color: #999b99"],
["1966",1,"color: #999b99"],
["1967",2,"color: #999d99"],
["1972",1,"color: #999b99"],
["1981",9,"color: #99ac99"],
["1982",4,"color: #99a199"],
["1983",7,"color: #99a899"],
["1984",8,"color: #99aa99"],
["1985",6,"color: #99a699"],
["1986",5,"color: #99a499"],
["1987",12,"color: #99b399"],
["1988",5,"color: #99a499"],
["1989",7,"color: #99a899"],
["1990",5,"color: #99a499"],
["1991",8,"color: #99aa99"],
["1992",13,"color: #99b599"],
["1993",8,"color: #99aa99"],
["1994",16,"color: #99bc99"],
["1995",23,"color: #99cc99"],
["1996",4,"color: #99a199"],
["1997",10,"color: #99af99"],
["1998",2,"color: #999d99"],
["1999",4,"color: #99a199"],
["2000",4,"color: #99a199"],
["2001",3,"color: #999f99"],
["2002",3,"color: #999f99"],
["2003",4,"color: #99a199"],
["2004",4,"color: #99a199"],
["2005",2,"color: #999d99"],
["2006",5,"color: #99a499"],
["2009",1,"color: #999b99"],
["2011",1,"color: #999b99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии П-55 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии П-55 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.984295,37.165136],[55.988117,37.157159],[55.700628,37.851754],[55.699218,37.854449],[55.775322,37.489850],[55.758737,37.820825],[55.758311,37.820502],[55.747844,37.817313],[55.870950,37.569135],[55.872885,37.568309],[55.874804,37.567536],[55.876046,37.566916],[55.877617,37.566368],[55.878692,37.566162],[55.876748,37.709488],[55.682234,37.855581],[55.545992,37.529852],[55.630944,37.479906],[55.629450,37.478127],[55.628647,37.475531],[55.543516,37.511544],[55.662273,37.532816],[55.661877,37.529807],[55.636356,37.747639],[55.634237,37.748601],[55.542202,37.512640],[55.686127,37.920871],[55.686051,37.857953],[55.683011,37.854404],[55.681250,37.852275],[55.852834,37.438071],[55.879662,37.571597],[55.806287,37.417994],[55.826068,37.807458],[55.636717,37.671166],[55.637088,37.667519],[55.637347,37.663836],[55.637459,37.660575],[55.636255,37.678649],[55.636448,37.675648],[55.864293,37.592258],[55.865621,37.593587],[55.795089,37.574022],[55.794953,37.572288],[55.587031,37.674777],[55.624281,37.664958],[55.623722,37.665884],[55.652105,37.744037],[55.724089,37.621390],[55.724900,37.621696],[55.724829,37.623151],[55.728322,37.622504],[55.722294,37.621534],[55.721265,37.623196],[55.726583,37.622064],[55.878117,37.698906],[55.877041,37.697783],[55.536405,37.580526],[55.537928,37.580921],[55.539574,37.581307],[55.772193,37.489571],[55.711584,37.755302],[55.712431,37.758554],[55.710788,37.752050],[55.742787,37.403621],[55.889386,37.675532],[55.890643,37.675163],[55.892117,37.674813],[55.859256,37.602058],[55.745407,37.785638],[55.703175,37.845547],[55.872546,37.590515],[55.846517,37.454753],[55.862878,37.447431],[55.865354,37.446470],[55.824187,37.803874],[55.824723,37.804790],[55.825285,37.805814],[55.878814,37.700882],[55.871147,37.590416],[55.717523,37.407295],[55.822837,37.757260],[55.823798,37.758275],[55.824026,37.759300],[55.741070,37.432232],[55.854517,37.683060],[55.879435,37.723115],[55.852501,37.680320],[55.784916,37.447917],[55.786465,37.447935],[55.856432,37.449641],[55.858554,37.448833],[55.800691,37.571704],[55.801283,37.571659],[55.801374,37.570330],[55.802664,37.569512],[55.802422,37.568713],[55.687066,37.566970],[55.682610,37.453765],[55.841134,37.527768],[55.841311,37.529151],[55.707912,37.481460],[55.706944,37.481864],[55.705858,37.480750],[55.705387,37.479950],[55.721128,37.567087],[55.822149,37.512074],[55.737461,37.584631],[55.724778,37.567069],[55.869849,37.660314],[55.828142,37.583661],[55.827100,37.585278],[55.826159,37.586778],[55.877304,37.679673],[55.875324,37.674535],[55.682305,37.454654],[55.681828,37.453693],[55.775251,37.642195],[55.788196,37.615066],[55.671747,37.746157],[55.703946,37.845098],[55.702368,37.848466],[55.545997,37.531927],[55.864783,37.475755],[55.689583,37.860477],[55.687731,37.859345],[55.567519,37.566961],[55.567519,37.566961],[55.567219,37.569171],[55.573831,37.582071],[55.577907,37.576843],[55.578503,37.574004],[55.578528,37.572603],[55.568313,37.587632],[55.569286,37.583472],[55.742874,37.852545],[55.742417,37.855734],[55.742990,37.858141],[55.743036,37.859111],[55.743406,37.862354],[55.744556,37.868014],[55.744733,37.869460],[55.745022,37.870430],[55.745448,37.872721],[55.745909,37.875056],[55.589274,37.640659],[55.648062,37.470042],[55.664218,37.747217],[55.668198,37.764007],[55.687335,37.564123],[55.677712,37.444440],[55.719906,37.412056],[55.852192,37.438206],[55.673184,37.816828],[55.865793,37.598250],[55.867667,37.592258],[55.862439,37.608859],[55.873541,37.705095],[55.683133,37.585449],[55.674199,37.748358],[55.673879,37.749508],[55.893970,37.542024],[55.875087,37.676205],[55.731881,37.589743],[55.830407,37.580104],[55.865384,37.679026],[55.676834,37.444826],[55.651242,37.725298],[55.869071,37.443488],[55.764420,37.702706],[55.740700,37.847990],[55.798303,37.402875],[55.798141,37.396497],[55.707781,37.742869],[55.707187,37.741360],[55.706776,37.740354],[55.718654,37.511275],[55.859670,37.499839],[55.826832,37.825290],[55.806125,37.614644],[55.539487,37.532187],[55.535121,37.517752],[55.535473,37.514967],[55.892345,37.541395],[55.664136,37.293927],[55.662928,37.291098],[55.896357,37.542356],[60.004600,30.452798],[60.004942,30.453840],[59.955741,30.428238],[59.963917,30.303004],[60.009008,30.432595],[55.749258,38.000147],[55.408900,37.559936],[55.681646,37.866082]];
let forURL = [1660,1663,6878,6879,6944,7456,7459,7470,8401,8403,8405,8409,8410,8411,9800,10490,10617,10839,10843,10848,11079,11114,11116,12716,12717,13016,13937,14399,14402,14407,14477,16716,16808,16943,16956,16974,16975,16984,16987,16999,17030,17033,17252,17254,19136,19303,19305,19398,19447,19448,19449,19450,19451,19455,19460,19590,19591,20434,20435,20436,20862,22802,22809,22843,23073,23107,23108,23109,23247,24241,25175,25787,26358,26397,26415,28657,28658,28659,29699,31165,32025,32105,32106,32107,32336,32752,32763,32776,2947,2951,26383,29217,3652,3653,3654,3655,3656,17278,4481,9536,9537,13347,13348,13349,13350,15973,16379,16453,17771,20473,20605,20607,20609,23111,23114,23272,25089,27185,28382,5961,6882,6883,10615,12184,14388,14391,14913,14914,14951,25727,27337,27343,27344,27366,27369,27692,27699,27702,27703,27706,27709,27710,27711,27713,27716,9481,10741,13453,13468,16493,21660,32013,14480,14676,15150,15166,15154,23337,15277,18265,18273,31484,19056,19361,20614,26023,23287,24133,26427,27086,27682,27903,27913,28142,28150,28148,28641,28969,29377,30281,30664,30689,30692,31476,101581,101583,31489,43357,43358,47186,52972,53615,71678,77269,94744];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии П-55</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии П-55 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии П-55</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>26772</strong> квартир.</li>
<li>Проживает <strong>31072</strong> семей <small>(<strong>171092</strong> человек)</small>.</li>
<li><strong>1724085.9 м²</strong> жилых помещений.</li>
<li><strong>232384.8 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>70828.3 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии П-55&nbsp;<strong>60.80%</strong>. Минимальный&nbsp;<strong>1.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;П-55, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,368 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:29:49.428154+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:29:49.428202+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:29:49.428224+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии 1Р-303: детальная информация" />
<meta name="keywords" content=" 1Р-303, серия 1Р-303, проект 1Р-303, года постройки зданий серии 1Р-303, размеры окон в домах серии 1Р-303, оконные проемы зданий серии 1Р-303, дома серии 1Р-303 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии 1Р-303 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия 1Р-303</li>
</ol>
<h1>СЕРИЯ 1Р-303</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии 1Р-303: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/062x132H210WN(G).png" alt="Окно одностворчатое на балкон для серии 1P-303. Размер 620x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое на балкон для серии 1P-303. Размер 620x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:73px;min-width:13ex;">
<nobr>620×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно одностворчатое на балкон для серии 1P-303<br />
<a href="/tsena-odnogo-okna/620x1320mm/tip73">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/120x132H210WN(G)(L_).png" alt="Окно двустворчатое на балкон для серии 1P-303. Размер 1200x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое на балкон для серии 1P-303. Размер 1200x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:142px;min-width:13ex;">
<nobr>1200×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Окно двустворчатое на балкон для серии 1P-303<br />
<a href="/tsena-odnogo-okna/1200x1320mm/tip74">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/068x210H210D-(G).png" alt="Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504. Размер 680x2100 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504. Размер 680x2100 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:80px;min-width:13ex;">
<nobr>680×2100&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Дверь на балкон для серий 1P-303, 1P-303.16 и 1ЛГ-504<br />
<a href="/tsena-odnogo-okna/680x2100mm/tip77">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/128x132H210W-(G)(L).png" alt="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:152px;min-width:13ex;">
<nobr>1280×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно двустворчатое для серии МГ-601 и 1P-303<br />
<a href="/tsena-odnogo-okna/1280x1320mm/tip52">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap4">
<div><img src="/static/img/_flap.cfg/186x132H210W-(G)(L_)(L).png" alt="Окно трёхстворчатое для серии 1P-303. Размер 1860x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии 1P-303. Размер 1860x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:221px;min-width:13ex;">
<nobr>1860×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
Окно трёхстворчатое для серии 1P-303<br />
<a href="/tsena-odnogo-okna/1860x1320mm/tip72">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1Р-303</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия 1Р-303: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1960",2,"color: #999e99"],
["1964",6,"color: #99aa99"],
["1965",6,"color: #99aa99"],
["1966",5,"color: #99a799"],
["1967",5,"color: #99a799"],
["1968",7,"color: #99ac99"],
["1969",6,"color: #99aa99"],
["1970",7,"color: #99ac99"],
["1971",10,"color: #99b599"],
["1972",7,"color: #99ac99"],
["1973",11,"color: #99b899"],
["1974",11,"color: #99b899"],
["1975",5,"color: #99a799"],
["1976",8,"color: #99af99"],
["1977",3,"color: #99a199"],
["1978",5,"color: #99a799"],
["1979",2,"color: #999e99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии 1Р-303 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии 1Р-303 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.476082,37.305048],[55.474919,37.303701],[56.014202,37.467644],[56.015701,37.463933],[56.014806,37.462900],[56.015877,37.462712],[56.015228,37.462505],[56.014705,37.462029],[56.014594,37.466772],[56.014947,37.465604],[55.650785,37.407268],[55.790762,37.966235],[55.790534,37.968886],[55.792706,37.960441],[55.791425,37.960414],[55.791218,37.961052],[55.791946,37.962445],[55.792792,37.964448],[55.791987,37.965616],[55.793288,37.968957],[55.893480,37.451088],[55.893415,37.450072],[56.369417,37.531586],[56.365553,37.532717],[56.369177,37.539958],[56.364486,37.532484],[56.364815,37.533086],[56.363892,37.534029],[56.364002,37.534981],[56.365523,37.539266],[56.366206,37.539724],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.348422,37.524992],[56.354193,37.549983],[56.341488,37.519647],[56.341318,37.520716],[56.341099,37.521776],[56.334408,37.535655],[56.334752,37.536526],[56.338509,37.546956],[56.336987,37.546911],[56.336423,37.545968],[56.337806,37.548061],[56.338444,37.547630],[56.337875,37.547288],[56.338130,37.548869],[56.341064,37.547270],[56.337257,37.552193],[56.337027,37.549327],[56.339682,37.544962],[56.338404,37.519126],[56.337716,37.515111],[56.340161,37.536212],[56.339732,37.538296],[56.355894,37.527741],[56.341702,37.518533],[56.339382,37.518785],[56.284079,37.486760],[56.283480,37.488269],[56.283405,37.487640],[55.939802,36.710148],[55.939958,36.711603],[55.939303,36.711828],[55.939504,36.712574],[55.940427,36.712583],[55.939313,36.709169],[55.938632,36.709421],[55.938859,36.710157],[55.906471,37.729997],[55.904195,37.726574],[55.901031,37.723825],[55.900153,37.722837],[55.899320,37.721840],[55.898492,37.722828],[55.906592,37.728649],[55.892092,37.715695],[55.892274,37.714923],[55.943240,37.777158],[55.907460,37.728631],[55.909060,37.725200],[55.908439,37.723690],[55.905719,37.731874],[55.906254,37.730940],[55.891850,37.716576],[56.458328,38.093087],[56.738616,37.532969],[56.738611,37.531631],[56.739031,37.530948],[56.739322,37.528172],[56.739994,37.528684],[56.741134,37.529376],[56.741573,37.529484],[56.742773,37.529430],[56.742462,37.538341],[56.725561,37.516126],[56.738942,37.528936],[56.740749,37.528531],[55.694885,37.750963],[56.047650,37.481855],[56.047042,37.481271],[56.046509,37.480256],[56.048329,37.482232],[56.047243,37.480714],[56.048053,37.482798],[56.046771,37.481729],[56.367946,37.536634],[56.319774,36.760005],[56.365069,37.538224],[56.366410,37.538898],[55.939857,36.713346],[55.942086,36.712133],[55.941556,36.712259],[55.941344,36.711630],[55.941133,36.710984],[55.939207,36.710957]];
let forURL = [2259,2263,75796,75797,75800,75802,75803,75804,75805,75807,14599,69570,69573,69963,69965,69966,69967,69968,69973,69976,81184,81199,86240,86246,86252,86260,86267,86272,86273,86275,86276,86283,86288,86290,86295,86296,86297,86299,86300,86301,86302,86304,86429,86449,86450,86451,86469,86470,86533,86540,86542,86544,86545,86546,86549,86550,86552,86554,86569,86570,86585,86595,86596,86613,86631,86677,86778,86779,86780,89386,89390,89391,89392,89394,89413,89414,89415,97269,97278,97290,97294,97298,97299,97308,97703,97704,98024,98059,98068,98069,98076,98079,98090,109134,111240,111241,111242,111247,111248,111249,111252,111257,111266,111302,114852,114853,114854,83160,83161,83162,83167,83169,83175,83176,86243,91347,86274,86277,89393,89395,89396,89397,89398,89416];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии 1Р-303</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии 1Р-303 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии 1Р-303</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>7899</strong> квартир.</li>
<li>Проживает <strong>9247</strong> семей <small>(<strong>45176</strong> человек)</small>.</li>
<li><strong>345222.8 м²</strong> жилых помещений.</li>
<li><strong>64146.2 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>0.0 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии 1Р-303&nbsp;<strong>60.00%</strong>. Минимальный&nbsp;<strong>10.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;1Р-303, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,379 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:30:35.978140+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:35.978187+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:30:35.978209+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии МГ-601: детальная информация" />
<meta name="keywords" content=" МГ-601, серия МГ-601, проект МГ-601, года постройки зданий серии МГ-601, размеры окон в домах серии МГ-601, оконные проемы зданий серии МГ-601, дома серии МГ-601 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии МГ-601 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия МГ-601</li>
</ol>
<h1>СЕРИЯ МГ-601</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии МГ-601: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/117x132H225WN(G).png" alt="Окно одностворчатое, балкон для серии МГ-601. Размер 1170x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое, балкон для серии МГ-601. Размер 1170x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:130px;min-width:13ex;">
<nobr>1170×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно одностворчатое, балкон для серии МГ-601<br />
<a href="/tsena-odnogo-okna/1170x1320mm/tip53">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/167x132H225WN(G)(L)(L).png" alt="Окно трёхстворчатое, балкон для серии МГ-601. Размер 1670x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое, балкон для серии МГ-601. Размер 1670x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:185px;min-width:13ex;">
<nobr>1670×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Окно трёхстворчатое, балкон для серии МГ-601<br />
<a href="/tsena-odnogo-okna/1670x1320mm/tip54">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/082x225H225D-(L).png" alt="Дверь на балкон для серии II-68 и МГ-601. Размер 820x2250 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии II-68 и МГ-601. Размер 820x2250 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:91px;min-width:13ex;">
<nobr>820×2250&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Дверь на балкон для серии II-68 и МГ-601<br />
<a href="/tsena-odnogo-okna/820x2250mm/tip19">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/128x132H225W-(G)(L).png" alt="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии МГ-601 и 1P-303. Размер 1280x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:142px;min-width:13ex;">
<nobr>1280×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно двустворчатое для серии МГ-601 и 1P-303<br />
<a href="/tsena-odnogo-okna/1280x1320mm/tip52">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap4">
<div><img src="/static/img/_flap.cfg/194x132H225W-(G)(L)(L).png" alt="Окно трёхстворчатое для серии МГ-601. Размер 1940x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии МГ-601. Размер 1940x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:215px;min-width:13ex;">
<nobr>1940×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
Окно трёхстворчатое для серии МГ-601<br />
<a href="/tsena-odnogo-okna/1940x1320mm/tip51">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap5">
<div><img src="/static/img/_flap.cfg/258x132H225W-(G)(L)(G)(L).png" alt="Окно четырёхстворчатое для серии МГ-601. Размер 2580x1320 (Ш х В, мм.). Типовая схема открывания." title="Окно четырёхстворчатое для серии МГ-601. Размер 2580x1320 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:286px;min-width:13ex;">
<nobr>2580×1320&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markF.svg');"></span></nobr><br />
Окно четырёхстворчатое для серии МГ-601<br />
<a href="/tsena-odnogo-okna/2580x1320mm/tip50">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии МГ-601</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия МГ-601: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1963",2,"color: #99a099"],
["1964",1,"color: #999c99"],
["1965",1,"color: #999c99"],
["1966",4,"color: #99a799"],
["1967",9,"color: #99b999"],
["1968",7,"color: #99b299"],
["1969",12,"color: #99c499"],
["1970",10,"color: #99bd99"],
["1971",13,"color: #99c899"],
["1972",14,"color: #99cc99"],
["1973",8,"color: #99b699"],
["1974",3,"color: #99a399"],
["1975",6,"color: #99ae99"],
["1976",4,"color: #99a799"],
["1977",1,"color: #999c99"],
["1978",1,"color: #999c99"],
["1979",3,"color: #99a399"],
["1988",1,"color: #999c99"],
["1993",1,"color: #999c99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии МГ-601 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии МГ-601 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.725919,37.465919],[55.725189,37.461885],[55.726644,37.469791],[55.746056,37.593542],[55.658830,37.497701],[55.659302,37.497153],[55.658820,37.496587],[55.659277,37.496057],[55.660815,37.487236],[55.657545,37.492994],[55.658865,37.490182],[55.660754,37.493021],[55.728327,37.520752],[55.749288,37.793894],[55.749623,37.793480],[55.750175,37.796490],[55.749841,37.796903],[55.748432,37.787004],[55.748098,37.787408],[55.681316,37.665857],[55.679138,37.665444],[55.674534,37.500576],[55.673854,37.499291],[55.673169,37.498016],[55.671727,37.495455],[55.668295,37.514607],[55.667213,37.513008],[55.666142,37.511356],[55.669366,37.516215],[55.753139,37.823772],[55.753022,37.824553],[55.775510,37.685988],[55.767681,37.666917],[55.749035,37.790318],[55.748706,37.790714],[55.709906,37.503846],[55.709429,37.502983],[55.708942,37.502148],[55.778669,37.476249],[55.680559,37.671399],[55.702495,37.669881],[55.675687,37.664824],[55.674306,37.665147],[55.675017,37.664985],[55.672422,37.496731],[55.670448,37.517761],[55.652415,37.598851],[55.651572,37.598878],[55.776391,37.687659],[55.710748,37.393542],[55.711072,37.394530],[55.711600,37.395697],[55.709186,37.475962],[55.630878,37.599552],[55.630583,37.598330],[55.709617,37.474695],[55.708668,37.474264],[55.703160,37.469719],[55.702652,37.467958],[55.703454,37.468021],[55.704681,37.460610],[55.705239,37.461499],[55.705767,37.460161],[55.704641,37.476717],[55.705138,37.475423],[55.704037,37.474794],[55.707537,37.467069],[55.706756,37.466027],[55.707755,37.465640],[55.857523,37.496345],[55.858710,37.494602],[55.855487,37.498276],[55.855775,37.497791],[55.856361,37.502444],[55.856790,37.502381],[55.857468,37.507574],[55.857705,37.506927],[55.658982,37.512559],[55.658413,37.513125],[55.658520,37.515039],[55.658048,37.514607],[55.656204,37.516144],[55.655742,37.515802],[55.859069,37.505651],[55.859281,37.504987],[55.859888,37.498716],[55.858347,37.500702],[55.860741,37.502992],[55.860524,37.503630],[55.653903,37.559541],[55.654295,37.559415],[55.637266,37.512793],[55.859413,37.498797],[55.797260,37.725217],[55.797776,37.728263],[55.796719,37.721993],[55.619411,37.592240],[55.691232,37.590874],[55.691775,37.590758],[59.829739,30.332676],[60.013344,30.260388]];
let forURL = [1239,1241,1246,3593,6780,6781,6782,6783,10315,10329,10341,10344,4321,12895,12896,12899,12900,13783,13784,6001,6002,6151,6162,6169,6181,6727,6737,6752,6869,7715,7716,11833,11972,12890,12891,21132,21133,21134,21596,27608,28404,6005,6013,6008,6174,6864,10704,10706,11836,12123,12124,12125,13388,30064,30065,13390,13391,20280,20282,20283,20295,20296,20297,20304,20305,20307,21687,21688,21689,19472,19475,19480,19483,29155,29156,29160,29161,22667,22670,22671,22675,22680,22681,22984,22985,28966,28972,28981,28984,29498,29500,23149,28964,29820,29824,29892,29980,30228,30229,40658,41168];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии МГ-601</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии МГ-601 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии МГ-601</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>13011</strong> квартир.</li>
<li>Проживает <strong>13342</strong> семей <small>(<strong>57998</strong> человек)</small>.</li>
<li><strong>654281.7 м²</strong> жилых помещений.</li>
<li><strong>89075.3 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>22511.2 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии МГ-601&nbsp;<strong>42.00%</strong>. Минимальный&nbsp;<strong>14.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;МГ-601, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
@@ -0,0 +1,362 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:30:12.705452+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:12.705501+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:30:12.705527+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии ГМС-2001: детальная информация" />
<meta name="keywords" content=" ГМС-2001, серия ГМС-2001, проект ГМС-2001, года постройки зданий серии ГМС-2001, размеры окон в домах серии ГМС-2001, оконные проемы зданий серии ГМС-2001, дома серии ГМС-2001 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии ГМС-2001 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия ГМС-2001</li>
</ol>
<h1>СЕРИЯ ГМС-2001</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии ГМС-2001: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/116x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ. Размер 1160x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:134px;min-width:13ex;">
<nobr>1160×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно двустворчатое, балкон для серий ГМС-1, П-44, ПД-4 и КОПЭ<br />
<a href="/tsena-odnogo-okna/1160x1420mm/tip2">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/146x142H216WN(G)(L_).png" alt="Окно двустворчатое, балкон для серии КОПЭ и П-44T. Размер 1460x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон для серии КОПЭ и П-44T. Размер 1460x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:168px;min-width:13ex;">
<nobr>1460×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Окно двустворчатое, балкон для серии КОПЭ и П-44T<br />
<a href="/tsena-odnogo-okna/1460x1420mm/tip8">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/067x216H216D-(L).png" alt="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4. Размер 670x2160 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:77px;min-width:13ex;">
<nobr>670×2160&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Дверь на балкон для серии ГМС-1, П-3, П-42, П-43, П-55 и ПД-4<br />
<a href="/tsena-odnogo-okna/670x2160mm/tip16">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/077x142H216W-(G).png" alt="Окно одностворчатое для серий ГМС-1. Размер 770x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно одностворчатое для серий ГМС-1. Размер 770x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:89px;min-width:13ex;">
<nobr>770×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно одностворчатое для серий ГМС-1<br />
<a href="/tsena-odnogo-okna/770x1420mm/tip46">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap4">
<div><img src="/static/img/_flap.cfg/147x142H216W-(G)(L_).png" alt="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ. Размер 1470x1420 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:170px;min-width:13ex;">
<nobr>1470×1420&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
Окно двустворчатое для ГМС-1, П-30/44/46/55, ПД-4, 1-504 и КОПЭ<br />
<a href="/tsena-odnogo-okna/1470x1420mm/tip1">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии ГМС-2001</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия ГМС-2001: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["2003",5,"color: #99ae99"],
["2004",7,"color: #99b699"],
["2005",6,"color: #99b299"],
["2006",5,"color: #99ae99"],
["2007",5,"color: #99ae99"],
["2008",8,"color: #99bb99"],
["2009",12,"color: #99cc99"],
["2010",8,"color: #99bb99"],
["2011",10,"color: #99c399"],
["2012",2,"color: #99a199"],
["2013",3,"color: #99a599"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии ГМС-2001 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии ГМС-2001 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.820182,37.873143],[55.698203,37.914915],[55.698903,37.915831],[55.700735,37.917484],[55.658068,37.602067],[55.842302,37.550890],[55.843555,37.553073],[55.844667,37.556208],[55.845213,37.556235],[55.866031,37.472135],[55.866389,37.473168],[55.682468,37.928318],[55.713537,37.402794],[55.714090,37.401662],[55.713922,37.400719],[55.872097,37.558526],[55.876496,37.485969],[55.877157,37.485807],[55.544290,37.565380],[55.544036,37.566072],[55.844177,37.548896],[55.841807,37.549597],[55.670153,37.791145],[55.669650,37.790507],[55.505159,37.576492],[55.671153,37.791944],[55.672326,37.794379],[55.681128,37.924230],[55.681275,37.926862],[55.532029,37.502786],[55.701815,37.915382],[55.700826,37.914367],[55.712964,37.894020],[55.714247,37.887875],[55.922404,37.542599],[55.923392,37.543120],[55.927694,37.545276],[55.928718,37.544009],[55.926469,37.540138],[55.419136,37.495123],[55.417526,37.496758],[55.421987,37.483211],[55.421767,37.482178],[55.421118,37.481639],[55.415324,37.481001],[55.415027,37.483930],[55.414910,37.481819],[55.833461,37.286840],[55.833137,37.285295],[55.832586,37.288142],[55.878248,37.509478],[55.879571,37.511212],[55.826584,37.593650],[55.827530,37.593605],[55.827408,37.595330],[55.713755,37.889762],[55.668655,37.789914],[55.713136,37.891657],[55.745042,37.986313],[55.745068,37.983321],[55.744835,37.984884],[55.743603,37.985630],[55.742585,37.985073],[55.744110,37.982782],[55.416887,37.480939],[55.416346,37.480678],[55.415860,37.481208],[55.418252,37.499480],[55.419008,37.498959],[55.419861,37.498788],[55.420219,37.497683]];
let forURL = [3325,6419,6425,6428,10726,11198,11201,11208,11209,12167,12171,13930,14103,14118,14119,15680,15777,15778,16681,16682,19168,19173,19733,19734,20017,20210,20211,21700,21701,23098,25893,25915,26433,26444,31497,31499,31503,31504,31509,77303,77304,77322,77324,77325,77340,77500,77501,92345,92346,92348,11723,11724,19721,19722,19723,26448,20206,26450,71418,71419,71420,71421,71422,71423,77333,77336,77338,78458,78459,78473,78474];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии ГМС-2001</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии ГМС-2001 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии ГМС-2001</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>12585</strong> квартир.</li>
<li>Проживает <strong>18198</strong> семей <small>(<strong>64618</strong> человек)</small>.</li>
<li><strong>862529.2 м²</strong> жилых помещений.</li>
<li><strong>188963.6 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>28750.5 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии ГМС-2001&nbsp;<strong>8.10%</strong>. Минимальный&nbsp;<strong>1.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;ГМС-2001, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,357 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:30:08.002217+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:30:08.002293+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:30:08.002332+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии II-66: детальная информация" />
<meta name="keywords" content=" II-66, серия II-66, проект II-66, года постройки зданий серии II-66, размеры окон в домах серии II-66, оконные проемы зданий серии II-66, дома серии II-66 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии II-66 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия II-66</li>
</ol>
<h1>СЕРИЯ II-66</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии II-66: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/137x154H222WN(G)(L_).png" alt="Окно двустворчатое, балкон, для серий II-66. Размер 1370x1540 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон, для серий II-66. Размер 1370x1540 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:154px;min-width:13ex;">
<nobr>1370×1540&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно двустворчатое, балкон, для серий II-66<br />
<a href="/tsena-odnogo-okna/1370x1540mm/tip56">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/068x222H222D-(L).png" alt="Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66. Размер 680x2220 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66. Размер 680x2220 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:76px;min-width:13ex;">
<nobr>680×2220&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Дверь на балкон для серии 1-447, 1-464, 1-605 и II-66<br />
<a href="/tsena-odnogo-okna/680x2220mm/tip32">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/127x154H222W-(G_)(L).png" alt="Окно двустворчатое для серии II-66. Размер 1270x1540 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серии II-66. Размер 1270x1540 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:143px;min-width:13ex;">
<nobr>1270×1540&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Окно двустворчатое для серии II-66<br />
<a href="/tsena-odnogo-okna/1270x1540mm/tip55">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии II-66</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия II-66: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1971",1,"color: #999f99"],
["1972",1,"color: #999f99"],
["1973",1,"color: #999f99"],
["1974",1,"color: #999f99"],
["1975",3,"color: #99ac99"],
["1976",2,"color: #99a599"],
["1978",2,"color: #99a599"],
["1979",3,"color: #99ac99"],
["1980",3,"color: #99ac99"],
["1981",8,"color: #99cc99"],
["1982",6,"color: #99bf99"],
["1983",8,"color: #99cc99"],
["1984",6,"color: #99bf99"],
["1985",3,"color: #99ac99"],
["1986",2,"color: #99a599"],
["1987",7,"color: #99c599"],
["1988",1,"color: #999f99"],
["1989",2,"color: #99a599"],
["1990",2,"color: #99a599"],
["1991",1,"color: #999f99"],
["1994",2,"color: #99a599"],
["1995",1,"color: #999f99"],
["1998",1,"color: #999f99"],
["2005",1,"color: #999f99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии II-66 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии II-66 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.895298,37.535026],[55.591986,37.669953],[55.771925,37.572369],[55.770071,37.572980],[55.770218,37.573546],[55.588415,37.669046],[55.588349,37.670034],[55.814113,37.967547],[55.814548,37.968355],[55.627768,37.864780],[55.627961,37.863504],[55.939807,37.497836],[55.431238,37.505876],[55.431856,37.506235],[55.432490,37.506415],[55.891042,37.410421],[55.890487,37.410879],[55.889876,37.411364],[55.890275,37.482358],[55.882444,37.417769],[55.883080,37.416844],[55.881172,37.419682],[55.881798,37.418721],[55.892642,37.365272],[55.815696,37.314526],[55.815362,37.314050],[55.814973,37.313618],[55.825679,37.314732],[55.826862,37.312819],[55.828061,37.310663],[55.824445,37.316825],[55.678352,37.880779],[55.675737,37.870376],[55.692064,37.888989],[55.905169,37.727724],[55.899239,37.716468],[55.899668,37.716333],[55.915251,37.773385],[55.915659,37.773340],[55.921365,37.784964],[55.925021,37.766747],[55.925354,37.766612],[55.923917,37.761330],[55.922399,37.789743],[55.923554,37.719459],[55.924159,37.720672],[55.917127,37.745349],[55.917647,37.744459],[55.905951,37.716459],[55.905003,37.715381],[55.903474,37.711707],[55.912783,37.750119],[55.914156,37.751376],[55.912748,37.718830],[55.912143,37.717752],[55.911568,37.716692],[55.913798,37.720807],[55.913338,37.719873],[55.677951,37.257680],[55.677605,37.258237],[55.676189,37.259297],[56.037503,37.245948],[56.037227,37.245867],[54.884239,38.060774],[54.884239,38.060774],[54.884514,38.090437],[54.879645,38.062876],[54.879422,38.066514],[54.879479,38.065275],[54.884327,38.062059],[55.907753,37.719019],[55.906920,37.717573],[55.903474,37.711707],[55.914862,37.752032]];
let forURL = [564,12389,15033,15035,15036,18916,18917,69404,69410,70384,70385,70734,77137,77138,77140,80836,80837,80848,80997,81148,81149,81173,81180,81484,92491,92492,92493,92503,92507,92516,92537,94721,94725,95117,97275,97345,97346,97412,97413,97447,97564,97565,97570,97612,97648,97649,97660,97662,97763,97765,97770,98136,98139,98192,98197,98198,98236,98237,101184,101186,101187,110400,110401,110566,110567,110765,110772,110775,110777,110818,114847,114848,114849,114850];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии II-66</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии II-66 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии II-66</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>4295</strong> квартир.</li>
<li>Проживает <strong>5432</strong> семей <small>(<strong>28954</strong> человек)</small>.</li>
<li><strong>239948.6 м²</strong> жилых помещений.</li>
<li><strong>19670.9 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>0.0 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии II-66&nbsp;<strong>40.00%</strong>. Минимальный&nbsp;<strong>3.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;II-66, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
@@ -0,0 +1,382 @@
<!DOCTYPE html>
<html lang="ru-RU">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-language" content="ru" />
<meta http-equiv="Date" content="2023-01-18T00:29:30.132829+03:00" />
<meta http-equiv="Last-Modified" content="2023-01-18T00:29:30.133023+03:00" />
<meta http-equiv="Expires" content="2023-01-18T00:29:30.133044+03:00" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Дома серии 1-515/9: детальная информация" />
<meta name="keywords" content=" 1-515/9, серия 1-515/9, проект 1-515/9, года постройки зданий серии 1-515/9, размеры окон в домах серии 1-515/9, оконные проемы зданий серии 1-515/9, дома серии 1-515/9 на карте, установка окон, цены на пластиковые окна" />
<meta name="author" content="OKNARDIA.RU" />
<meta name="copyright" lang="ru" content="OKNARDIA.RU" />
<meta name="robots" content="index,follow" />
<meta name="document-state" content="Dynamic" />
<meta name="generator" content="OKNARDIA 0.3β by Python/Django" />
<title>Дома серии 1-515/9 — типовые проёмы, размеры окон, схемы открывания, планировки, здания на карте, история и статистика : ОКНАРДИЯ</title>
<link rel="alternate" href="https://oknardia.ru" hreflang="ru-ru" />
<link href="/static/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/bootstrap-theme.min.css" rel="stylesheet" type="text/css" />
<link href="/static/css/oknardia1.css" rel="stylesheet" type="text/css" />
<script src="/static/js/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="/static/js/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(window).load(function () {
let images = $('.half');
images.each(function (i) {
$(this).width($(this).width() / 2);
});
});
</script>
<script type="text/javascript">$(document).ready(function(){ $('#login-logout').load('/login-logout' ); })</script>
</head>
<body style="padding-top:70px;">
<!--- Контент НАЧАЛО --->
<div class="container-fluid">
<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/catalog/">Каталог</a></li>
<li><a href="/catalog/seria/">Типовые серии домов</a></li>
<li>Серия 1-515/9</li>
</ol>
<h1>СЕРИЯ 1-515/9</h1>
</div>
</div>
<div class="row">
<div class="col-md-12"></div>
</div>
<div class="row">
<div class="col-lg-10">
<h2 class="header">Дома серии 1-515/9: типовые размеры и схемы открывания</h2>
</div>
<div class="col-lg-12" style="padding:1em 0 0 0;margin-left:-1em">
<div class="win_discr pull-left" id="flap0">
<div><img src="/static/img/_flap.cfg/073x153H225WN(G).png" alt="Окно на балкон/лоджию для серии 1-515/9Ш и И-209А. Размер 730x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно на балкон/лоджию для серии 1-515/9Ш и И-209А. Размер 730x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:81px;min-width:13ex;">
<nobr>730×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markA.svg');"></span></nobr><br />
Окно на балкон/лоджию для серии 1-515/9Ш и И-209А<br />
<a href="/tsena-odnogo-okna/730x1530mm/tip36">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap1">
<div><img src="/static/img/_flap.cfg/132x153H225WN(G)(L_).png" alt="Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:146px;min-width:13ex;">
<nobr>1320×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markB.svg');"></span></nobr><br />
Окно двустворчатое, балкон, для серий II-18, II-68 и 1-515/9<br />
<a href="/tsena-odnogo-okna/1320x1530mm/tip22">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap2">
<div><img src="/static/img/_flap.cfg/076x225H225D-(L).png" alt="Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9. Размер 760x2250 (Ш х В, мм.). Типовая схема открывания." title="Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9. Размер 760x2250 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:84px;min-width:13ex;">
<nobr>760×2250&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markC.svg');"></span></nobr><br />
Дверь на балкон/лоджию для серии II-18, II-57, И-209А и 1-515/9<br />
<a href="/tsena-odnogo-okna/760x2250mm/tip37">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap3">
<div><img src="/static/img/_flap.cfg/132x153H225W-(G)(L_).png" alt="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9. Размер 1320x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:146px;min-width:13ex;">
<nobr>1320×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markD.svg');"></span></nobr><br />
Окно двустворчатое для серий II-18, II-68, II-49, К-7 и 1-515/9<br />
<a href="/tsena-odnogo-okna/1320x1530mm/tip23">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap4">
<div><img src="/static/img/_flap.cfg/149x113H225W-(G)(L).png" alt="Окно двустворчатое, кухня для серии 1-515/9. Размер 1490x1130 (Ш х В, мм.). Типовая схема открывания." title="Окно двустворчатое, кухня для серии 1-515/9. Размер 1490x1130 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:165px;min-width:13ex;">
<nobr>1490×1130&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markE.svg');"></span></nobr><br />
Окно двустворчатое, кухня для серии 1-515/9<br />
<a href="/tsena-odnogo-okna/1490x1130mm/tip35">цены только этого типового окна</a>
</div>
</div>
<div class="win_discr pull-left" id="flap5">
<div><img src="/static/img/_flap.cfg/188x153H225W-(G_)(G_)(L).png" alt="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." title="Окно трёхстворчатое для серии К9 и 1-515/9Ш. Размер 1880x1530 (Ш х В, мм.). Типовая схема открывания." itemprop="image" /></div>
<div class="caption" style="width:208px;min-width:13ex;">
<nobr>1880×1530&thinsp;мм.</nobr><br />
<nobr><b>1&thinsp;шт.</b><span class="color-bullet" style="background-image:url('/static/img/svg/markF.svg');"></span></nobr><br />
Окно трёхстворчатое для серии К9 и 1-515/9Ш<br />
<a href="/tsena-odnogo-okna/1880x1530mm/tip38">цены только этого типового окна</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<h3 class="header">Оконные проёмы в типовых квартирах <nobr>серии 1-515/9</nobr></h3>
</div>
<div class="col-lg-8 col-xs-12 col-md-offset-1">
<!--- прешаблон начало ---><table style="padding:2px;">{% for row in TABLE_OF_WINDOWS %}
<tr class="tr2">
<td>{{ row.APART_NAME|safe }}</td>{% for col in row.WIN_IN_APART %}
<td class="cntr">{% if col.WIN_ID %}<nobr title="{{ col.WIN_Q }} × {{ col.WIN_DESCRIPTION }}: {{ col.WIN_WIDTH }}шт.: {{ col.WIN_HEIGHT }} (Ш×В, см.). Схема открывания: {{ col.WIN_FLAPCFG }}">{% for I_II in col.WIN_NUM %}<span style="background-image:url('/static/img/svg/mark{{ I_II }}.svg');">&nbsp;</span>{% endfor %}</nobr>{% else %}—{% endif %}</td>{% endfor %}
<td style="background:#f9f9f9;"><a href="#{{ row.APART_ID }}" class="badge" title="Оконных предложений для квартиры: {{ row.NUM_OFFERS }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ row.NUM_OFFERS }}</a></td>
</tr>{% endfor %}
<tr class="trZ">
<td style="font-size: xx-small;vertical-align:text-top">© 2015-2023, данные: oknardia.ru</td>{% for i in WIN_OFFER_AND_MERCHANT %}
<td class="cntr" style="background:#f9f9f9;"><a href="/tsena-odnogo-okna/{{ i.WIN_W|floatformat:0 }}0x{{ i.WIN_H|floatformat:0 }}0mm/tip{{ i.WIN_ID }}" class="badge" title="Ценовых предложений для окна: {{ i.WIN_OFFER }}"><small class="glyphicon glyphicon-tags" aria-hidden="true"></small>&nbsp;{{ i.WIN_OFFER }}</a></td>{% endfor %}
<td></td>
</tr>
</table>
<!--- прешаблон конец ---></div>
</div>
<div class="row">
<div class="col-md-9"><a name="s_graph"></a>
<h2 class="header">Здания серия 1-515/9: ввод в&nbsp;эксплуатацию по&nbsp;годам</h2>
</div>
<div class="col-md-9 col-md-offset-1" style="height:300px;font-size:large;">
<script type="text/javascript" src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// google.charts.load('current', {'packages':['bar']});
// google.charts.setOnLoadCallback(drawChart);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
let data = google.visualization.arrayToDataTable([
["Год", "Введено в эксплуатацию", {role:'style'}],
["1968",4,"color: #99a799"],
["1969",11,"color: #99c199"],
["1970",8,"color: #99b699"],
["1971",6,"color: #99ae99"],
["1972",7,"color: #99b299"],
["1973",14,"color: #99cc99"],
["1974",11,"color: #99c199"],
["1975",9,"color: #99b999"],
["1976",5,"color: #99ab99"],
["1977",4,"color: #99a799"],
["1978",3,"color: #99a399"],
["1979",7,"color: #99b299"],
["1980",1,"color: #999c99"],
["1981",7,"color: #99b299"],
["1982",2,"color: #99a099"],
["1984",1,"color: #999c99"],
["1985",1,"color: #999c99"],
["1986",1,"color: #999c99"],
["1987",1,"color: #999c99"],
["1989",1,"color: #999c99"],
["1990",1,"color: #999c99"],
["1993",1,"color: #999c99"]
]);
let view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
2
]);
let options = {
animation:{
duration: 1500,
easing: 'in',
startup: true
},
backgroundColor: "#EEEEEE",
bar: {groupWidth: "76.4%"},
chartArea: {left: "2%", top: "5%", width: '96%', height: '85%'},
dataOpacity: 0.76,
explorer:{
maxZoomIn: 0.20,
maxZoomOut: 32 },
vAxis: {
baselineColor:'grey',
gridlines:{color: 'silver', count: 7},
minorGridlines:{color: '#dddddd', count: 3},
textPosition: 'in',
textStyle: {fontSize: 10}
},
hAxis: { textStyle: {fontSize: 10} },
isStacked: true,
tooltip: {
textStyle:{color: 'grey', fontSize: 10 },
trigger: 'selection'
},
annotations: {textStyle: { fontSize: 8, bold: true, color: 'black', opacity: 0.8 }},
legend: { position: "none" }
};
let chart = new google.visualization.ColumnChart(document.getElementById("graph"));
chart.draw(data, options);
}
</script>
<div id="graph" style="width:100%;height:100%">
<p>Для отображения гистограммы ввода в&nbsp;эксплуатацию зданий серии 1-515/9 нужна поддержка SVG.</p>
<noscript>
<p>Для визуализации отображения картографической информации с&nbsp;помощью Google.Charts нужно включить поддержку JavaScript.</p>
</noscript></div>
</div>
<div class="col-md-9 col-md-offset-1">
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
</div>
<div class="row">
<div class="col-md-7"><a name="s_map"></a>
<h2 class="header">Строения серии 1-515/9 на&nbsp;карте</h2>
</div>
<div class="col-md-7 col-lg-offset-1">
<p><small>Чтобы посмотреть цены на&nbsp;установку и&nbsp;замену окон от&nbsp;партнёров &laquo;Окнардия&raquo; в&nbsp;своей квартире: найдите дом на&nbsp;карте; кликните на&nbsp;него; перейдите по&nbsp;ссылке &laquo;Смотреть коммерческие предложения&raquo;. При необходимости смените типовую планировку квартиры (на&nbsp;странице ценовой выдачи, справа от&nbsp;изображения типовых проёмов и&nbsp;схем открывания).</small></p>
<div style="height:350px;">
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
let points = [[55.706944,37.827266],[55.621470,37.597926],[56.121496,37.057958],[55.868299,37.618947],[55.935370,37.549444],[56.006507,37.792510],[55.676448,37.745322],[55.675418,37.745295],[55.839673,37.418128],[55.840674,37.419539],[55.755824,37.826422],[55.756158,37.828739],[55.586390,37.664348],[55.585911,37.664860],[55.579556,37.666126],[55.589376,37.642123],[55.869455,37.442428],[55.875935,37.646274],[55.873142,37.647100],[55.872784,37.612829],[55.874067,37.623196],[55.873461,37.626070],[55.670031,37.649741],[55.668701,37.649418],[55.580034,37.663530],[55.680098,37.646786],[55.608287,37.707063],[55.607595,37.707000],[55.705102,37.792016],[55.612263,37.702715],[55.679164,37.759380],[55.714729,37.734425],[55.902374,37.711374],[55.902318,37.707575],[56.395522,37.994892],[56.395307,37.993257],[56.395063,37.991793],[55.585438,37.665390],[55.584451,37.667267],[55.599524,37.654107],[55.579811,37.664833],[55.583749,37.666459],[55.663984,37.743768],[55.861767,37.427920],[55.718334,37.731946],[55.620886,37.601627],[55.621292,37.600495],[55.874309,37.557367],[55.591299,37.661823],[55.619335,37.604232],[55.676149,37.743813],[55.677732,37.757620],[55.678336,37.758150],[55.678595,37.767016],[55.675636,37.747756],[55.795256,37.686204],[55.744865,37.993607],[55.745787,38.006606],[56.015017,37.460762],[55.715256,37.729484],[55.715576,37.730697],[55.715890,37.731775],[55.716711,37.732027],[55.695225,37.742106],[55.580854,37.666126],[55.757207,37.834354],[55.753767,37.834174],[55.753757,37.835144],[55.753737,37.836106],[55.757197,37.835324],[55.757182,37.836276],[55.755601,37.834273],[55.755581,37.835234],[55.755566,37.836195],[55.751898,37.835099],[55.779580,37.477759],[55.679560,37.758626],[55.678930,37.758383],[55.678570,37.759147],[55.678174,37.759030],[55.680153,37.759704],[55.747692,38.004980],[55.715515,37.734156],[55.872410,37.467751],[55.680270,37.766729],[55.883929,37.535188],[55.876789,37.535448],[55.878839,37.534739],[55.750976,37.834300],[55.766400,37.714222],[55.678580,37.673268],[55.873577,37.652157],[55.704621,37.738054],[55.666924,37.571408],[55.667396,37.574435],[55.826215,37.751287],[55.678692,37.680616],[55.876688,37.556846],[55.824243,37.808006],[55.795393,37.973709],[55.704854,37.362819],[55.666381,37.290774],[55.666452,37.289418],[55.666457,37.287891],[55.705092,37.365361],[56.121496,37.057958],[56.121496,37.057958]];
let forURL = [1058,15349,110408,1076,2725,3340,5957,5958,9077,9078,9183,9186,12400,12402,20810,9480,26428,9706,9752,9824,9854,9889,10984,10988,20808,21377,896,897,11095,15446,22449,26285,97772,98224,114886,114887,114888,12404,12409,17059,20809,12410,13444,13597,14855,15344,15345,15685,17057,17349,18206,18221,22427,18230,18262,23260,71398,71741,75466,19434,19436,19438,19439,19607,20811,21004,21021,21022,21023,21005,21006,21010,21011,21012,21032,21599,22423,22424,22425,22428,22445,71590,26286,26855,26917,27148,27161,27166,27293,27443,27607,27741,28186,29616,29641,32103,593,15687,16936,69952,102416,101316,101317,101318,102399,110409,110410];
ymaps.ready(function () {
let myMap = new ymaps.Map('SeriaMap', {
center: [55.75, 37.57],
zoom: 10,
behaviors: ['default', 'scrollZoom'],
controls: [ 'rulerControl', 'zoomControl', 'geolocationControl', 'fullscreenControl' ]
});
// Создадим кластеризатор, вызвав функцию-конструктор.
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedGrayClusterIcons',
groupByCoordinates: false,
hasHint: false,
viewportMargin: 0,
zoomMargin: 16,
clusterDisableClickZoom: false,
gridSize: 80
});
geoObjects = [];
add_str1 = '<a href="/';
add_str2 = '/0/">Смотреть коммерческие предложения</a>';
add_str3 = '<b>Здание серии 1-515/9</b>';
// Данные передаются в конструктор метки.
for(var i = 0, len = points.length; i < len; i++) {
geoObjects[i] = new ymaps.Placemark( points[i],
{ // Содержимое иконки, балуна и хинта.
balloonContent: add_str1 + forURL[i] + add_str2,
hintContent: add_str3
},
{ preset:'islands#circleIcon',iconColor: 'silver'} );
geoObjects[i].events
.add('mouseenter', function (e) {
e.get('target').options.set('preset', 'islands#yellowCircleIcon');
})
.add('mouseleave', function (e) {
e.get('target').options.set('preset', 'islands#grayCircleIcon');
});
}
// Добавляем метки в кластеризатор.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// позиционирование карты так, чтобы на ней были видны все объекты кластера.
myMap.setBounds(clusterer.getBounds(), { checkZoomRange: true });
});
</script>
<div id="SeriaMap" style="height:100%;width:100%;">
<noscript>
<p>Для отображения картографических данных по серии 1-515/9 с&nbsp;помощью &laquo;Яндекс.Карт&raquo; нужно включить поддержку JavaScript.</p>
</noscript>
</div></div>
<div style="font-size: xx-small;float: right">© 2015-2023, данные: oknardia.ru</div>
</div>
<diV class="col-md-4">
<h3 class="header">Статистика <nobr>серии 1-515/9</nobr></h3>
<p>Совокупно во&nbsp;всех зданиях типового проекта:</p>
<ul>
<li><strong>9781</strong> квартир.</li>
<li>Проживает <strong>18646</strong> семей <small>(<strong>85972</strong> человек)</small>.</li>
<li><strong>760689.2 м²</strong> жилых помещений.</li>
<li><strong>68401.4 м²</strong>&nbsp;— муниципальное жильё.</li>
<li><strong>43667.6 м²</strong> занимают государственные и&nbsp;городские службы, учреждения бытового обслуживания, магазины, офисы и&nbsp;тому подобное.</li>
<li>Максимальный износ жилого фонда серии 1-515/9&nbsp;<strong>46.00%</strong>. Минимальный&nbsp;<strong>10.00%</strong>. </li>
</ul>
</diV>
</div>
<div class="row">
<div class="col-md-4 col-lg-offset-8" style="margin-top: 1em;">
<h5>Информация о&nbsp;других, отличных от&nbsp;1-515/9, типовых сериях в&nbsp;базе &laquo;Окнардия&raquo;, типовых планировках квартир и&nbsp;оконных проёмах в&nbsp;них, а&nbsp;также рекомендации по&nbsp;замене&nbsp;окон:</h5>
<div class="href_d"><span><a href="/catalog/seria/1-335/all210/"><nobr>1-335</nobr></a></span><span><a href="/catalog/seria/1-447/all379/"><nobr>1-447</nobr></a></span><span><a href="/catalog/seria/1-510/all39/"><nobr>1-510</nobr></a></span><span><a href="/catalog/seria/1-511/all100/"><nobr>1-511</nobr></a></span><span><a href="/catalog/seria/1-5155/all41/"><nobr>1-515/5</nobr></a></span><span><a href="/catalog/seria/1-5159/all843/"><nobr>1-515/9</nobr></a></span><span><a href="/catalog/seria/1605/all375/"><nobr>1605</nobr></a></span><span><a href="/catalog/seria/1lg-502/all2420/"><nobr>1ЛГ-502</nobr></a></span><span><a href="/catalog/seria/1lg-504/all2100/"><nobr>1ЛГ-504</nobr></a></span><span><a href="/catalog/seria/1lg-507/all2105/"><nobr>1ЛГ-507</nobr></a></span><span><a href="/catalog/seria/1r-303/all3568/"><nobr>1Р-303</nobr></a></span><span><a href="/catalog/seria/1r-30316/all4080/"><nobr>1Р-303.16</nobr></a></span><span><a href="/catalog/seria/ii-18/all18/"><nobr>II-18</nobr></a></span><span><a href="/catalog/seria/ii-29/all72/"><nobr>II-29</nobr></a></span><span><a href="/catalog/seria/ii-49/all12/"><nobr>II-49</nobr></a></span><span><a href="/catalog/seria/ii-57/all68/"><nobr>II-57</nobr></a></span><span><a href="/catalog/seria/ii-66/all80/"><nobr>II-66</nobr></a></span><span><a href="/catalog/seria/ii-68/all24/"><nobr>II-68</nobr></a></span><span><a href="/catalog/seria/gms-2001/all522/"><nobr>ГМС-2001</nobr></a></span><span><a href="/catalog/seria/i-209a/all44/"><nobr>И-209А</nobr></a></span><span><a href="/catalog/seria/k-7/all19/"><nobr>К-7</nobr></a></span><span><a href="/catalog/seria/kope/all17/"><nobr>КОПЭ</nobr></a></span><span><a href="/catalog/seria/mg-601/all492/"><nobr>МГ-601</nobr></a></span><span><a href="/catalog/seria/p-3/all9/"><nobr>П-3</nobr></a></span><span><a href="/catalog/seria/p-30/all79/"><nobr>П-30</nobr></a></span><span><a href="/catalog/seria/p-43/all178/"><nobr>П-43</nobr></a></span><span><a href="/catalog/seria/p-44/all8/"><nobr>П-44</nobr></a></span><span><a href="/catalog/seria/p-44t/all22/"><nobr>П-44Т</nobr></a></span><span><a href="/catalog/seria/p-46/all29/"><nobr>П-46</nobr></a></span><span><a href="/catalog/seria/p-55/all255/"><nobr>П-55</nobr></a></span><span><a href="/catalog/seria/pd-4/all148/"><nobr>ПД-4</nobr></a></span></div>
<p style="text-align:right;padding-top:1em;padding-bottom:1em;"><a href="/stat_all/">Агрегированная информация<br />по&nbsp;типовым сериям домов<br />в&nbsp;базе &laquo;Окнардия&raquo;</a>.</p>
</div>
</div>
<div class="row">
{%include "report/report_last_user_visit.html" %}
{% include "report/report_log_user_visit.html" %}
</div>
</div>
<!---/ Контент КОНЕЦ --->
<nav class="navbar navbar-fixed-top navbar-default" role="navigation" id="header">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/"><nobr><img src="/static/img/oknardia_logo.svg" onerror="this.onerror=null;this.src='/static/img/oknardia_logo.gif';this.width=290;this.height=34" title="Перейти на гравную сраницу «Окнардия»" alt="Логотип «Окнардия — оконный агрегатор»" ></nobr></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="/catalog">Каталог</a></li>
<li><a href="/stat/rating/">Рейтинги</a></li>
<li><a href="/blog">Блог</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" rel="nofollow">О проекте <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/stat_all">Статистика</a></li>
<li role="separator" class="divider"></li>
<li><a href="/contact">Контакты</a></li>
<li><a href="/blogpost/2/My_zhdem_vashi_prajs-listy!">Сотрудничество</a></li>
<li><a href="/tariff">Услуги и тарифы</a></li>
<!-- li class="divider"></li>
<li><a href="#" rel="nofollow">Обратная связь</a></li -->
</ul>
</li>
<li class="dropdown" id="login-logout"><!--- Сюда подгружают AJAX-ом блок login-logout ---><small><br />Авторизации.<noscript style="color:red;">Для авторизации необходимо включить JavaScript.</noscript></small></li>
</ul>
</div>
</nav>
<div class="row panel-footer">
<div class="col-xs-12">
<span style="top:-200px;left:-8000px;position: absolute;"><script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-9116991-5', 'auto'); ga('send', 'pageview');
var _tmr=_tmr||[];_tmr.push({id:"2018432",type:"pageView",start:(new Date()).getTime()});(function (d,w,id){if(d.getElementById(id))return;var ts=d.createElement("script");ts.type="text/javascript";ts.async=true;ts.id=id;ts.src=(d.location.protocol=="https:"?"https:":"http:")+"//top-fwz1.mail.ru/js/code.js";var f=function(){var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(ts, s);};if(w.opera=="[object Opera]"){ d.addEventListener("DOMContentLoaded",f,false);}else{f();}})(document,window,"topmailru-code");
</script><noscript><div style="position:absolute;left:-10000px;">
<img src="//top-fwz1.mail.ru/counter?id=2018432;js=na" style="border:0;height:1px;width:1px" alt="" />
<img src="//mc.yandex.ru/watch/32997984" style="border:0;height:1px;width:1px" alt="" />
</div></noscript>
<a target="_blank" href="http://top.mail.ru/jump?from=2018432"><img src="//top-fwz1.mail.ru/counter?id=2018432;t=216;l=1" style="border:0;padding-top:8px;" rel="nofollow" alt="Рейтинг@Mail.ru"></a>
<a href="https://metrika.yandex.ru/stat/?id=32997984&amp;from=informer" target="_blank" rel="nofollow"><img src="https://informer.yandex.ru/informer/32997984/3_0_E0E0E0FF_C0C0C0FF_0_pageviews" style="width:88px; height:31px; border:0;" alt="Яндекс.Метрика" title="Яндекс.Метрика: данные за сегодня (просмотры, визиты и уникальные посетители)" onclick="try{Ya.Metrika.informer({i:this,id:32997984,lang:'ru'});return false}catch(e){}" /></a>
<span id="rambler"><script id="top100Counter" type="text/javascript" src="//counter.rambler.ru/top100.jcn?3148853"></script><noscript><a href="http://top100.rambler.ru/navi/3148853/"><img src="http://counter.rambler.ru/top100.cnt?3148853" alt="Rambler's Top100" border="0"/></a></noscript></span>
<script type="text/javascript"><!--
document.write("<a href='//www.liveinternet.ru/click' target=_blank><img src='//counter.yadro.ru/hit?t50.2;r"+escape(document.referrer)+((typeof(screen)=="undefined")?"":";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";"+Math.random()+"' alt='' title='LiveInternet' style='border:0;padding-top:8px;'><\/a>");
(function(d,w,c){(w[c]=w[c]||[]).push(function(){try{w.yaCounter32997984=new Ya.Metrika({id:32997984,clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true,trackHash:true});}catch(e){}});var n=d.getElementsByTagName("script")[0],s=d.createElement("script"),f=function(){n.parentNode.insertBefore(s,n);};s.type="text/javascript";s.async=true;s.src="https://mc.yandex.ru/metrika/watch.js";if(w.opera=="[object Opera]"){d.addEventListener("DOMContentLoaded",f,false);}else{ f();}})(document,window,"yandex_metrika_callbacks");
//--></script>
</span>
<small>© oknardia.ru, 2015-2023. <a href="/blogpost/18/Ob-avtorskih-pravah">Все права защищены</a>.<!--- Время отработки скрипта: сек---></small>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -2
View File
@@ -12,7 +12,6 @@
<ul>
<li><b><a href="/service/tmp">Страница для тестирования верстки текста в блоге</a></b></li>
</ul><ul>
<li><b><a href="/service/make_sitemaps">Пересоздать файлы sitemaps.xml</a></b> (исполняется около 10 минут)</li>
<li><a href="/service/make_JavaScripts4maps">Пересоздать JavaScript для карт на основе API Яндекс.Крат</a> (исполняется около 1 минуты)</li>
<li><a href="/service/make_SeriaInfoRoot">Построить id корневых серий</a> (исполняется около 1 часа)</li>
</ul><ul>
@@ -20,7 +19,7 @@
</ul><ul>
<li><a href="/service/make_FillGeoCode">Добавить GeoCode для адресов где его нет</a></li>
</ul><ul>
<li><a href="/service/make_Rating">Пересчитать рейтинги Профилей</a></li>
<li><b><a href="/service/make_rating">Пересчитать рейтинги Профилей</a></b></li>
</ul>
</body>
+3 -3
View File
@@ -201,7 +201,7 @@ def make_big_img_win_flap(img_file_name_with_path: str, width: int, height: int,
# height_door = int(height_door)
# создаем картинку с нужными размерами
img = Image.new("RGBA", (int(width * PICT_H / height_max), PICT_H), (255, 255, 255, 0))
print(img_file_name_with_path)
# print(img_file_name_with_path)
# находим крайние точки периметра (если окно -- выравнено вверх; если дверь -- вниз)
top = 0
left = 0
@@ -592,5 +592,5 @@ def touch_reload_wsgi(s: str = ''):
:return: None
"""
with open(TOUCH_RELOAD, 'a', encoding="utf-8") as f:
f.write(f'\nreload wsgi by cash-template {s}'
f' {django.utils.dateformat.format(django.utils.timezone.now(), "Y-m-d H:i:s")}')
f.write(f'\nreload wsgi by cash-template - {s} - '
f'{django.utils.dateformat.format(django.utils.timezone.now(), "Y-m-d H:i:s")}')
+3 -1013
View File
File diff suppressed because it is too large Load Diff
+161
View File
@@ -0,0 +1,161 @@
# -*- coding: utf-8 -*-
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse
from django.utils import timezone
from oknardia.models import (
MerchantBrand,
)
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
from web.add_func import get_rating_set_for_stars
import django.utils.dateformat
import time
import random
import re
import pytils
def catalog_company(request: HttpRequest) -> HttpResponse:
time_start = time.perf_counter()
to_template = {} # словарь, для передачи шаблону
q_company = MerchantBrand.objects.raw('SELECT'
' oknardia_merchantbrand.id,'
' oknardia_merchantbrand.sMerchantName,'
' oknardia_merchantbrand.pMerchantLogo,'
' oknardia_merchantbrand.sMerchantMainURL,'
' COUNT(oknardia_priceoffer.id) AS NumOffers,'
' AVG(oknardia_priceoffer.fOfferPrice) AS PriceAVG,'
' MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate,'
' Q.NumSets,'
' Q.RatingAVG,'
' 1 AS STARS '
'FROM (SELECT'
' COUNT(oknardia_setkit.sSetName) AS NumSets,'
' oknardia_merchantoffice.kMerchantName_id AS Q_ID,'
' AVG(oknardia_setkit.fSetRating) AS RatingAVG'
' FROM oknardia_merchantoffice'
' INNER JOIN oknardia_ouruser'
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
' INNER JOIN oknardia_setkit'
' ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id'
' GROUP BY oknardia_merchantoffice.id,'
' oknardia_merchantoffice.kMerchantName_id) AS Q,'
' oknardia_ouruser'
' INNER JOIN oknardia_merchantoffice'
' ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id'
' INNER JOIN oknardia_priceoffer'
' ON oknardia_priceoffer.kOfferFromUser_id = oknardia_ouruser.id'
' INNER JOIN oknardia_merchantbrand'
' ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id'
' WHERE Q_ID = oknardia_merchantoffice.kMerchantName_id '
'GROUP BY oknardia_merchantoffice.kMerchantName_id '
'ORDER BY Q.RatingAVG DESC;')
list_company = list(q_company)
for i in list_company:
i.STARS = get_rating_set_for_stars(i.RatingAVG)
i.NumSets = pytils.numeral.get_plural(i.NumSets, u"оконный набор, оконных набора, оконных наборов")
i.NumOffers = pytils.numeral.get_plural(i.NumOffers, u"вариант, варианта, вариантов")
i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U')))
i.sMerchantMainURL = pytils.translit.slugify(i.sMerchantName)
# print("NAME:", i.sMerchantName, "\tNumSets:", i.NumSets, "\tNumOffers:", i.NumOffers,
# "\t:AverageRating:", i.RatingAVG, "\tAveragePrice:", i.PriceAVG, "\tSTARS:", i.STARS)
to_template.update({
'COMPANIES': list_company,
# получаем последние визиты клиента через куки
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "catalog/catalog_company.html", to_template)
def catalog_company_detail(request: HttpRequest, company_id: str, company_name_slug: str) -> HttpResponse:
time_start = time.perf_counter()
to_template = {} # словарь, для передачи шаблону
company_id = int(company_id)
q_by_id = MerchantBrand.objects.get(id=company_id)
if pytils.translit.slugify(q_by_id.sMerchantName) != company_name_slug:
return redirect('/catalog/company/%d-%s' % (company_id, pytils.translit.slugify(q_by_id.sMerchantName)))
to_template.update({'COMPANY': q_by_id.sMerchantName})
to_template.update({'COMPANY_ID': company_id})
to_template.update({'COMPANY_T': company_name_slug})
list_not = [u"нет", u"", ""]
to_template.update({'LIST_NOT': list_not})
q_sets = MerchantBrand.objects.raw(f"SELECT"
f" COUNT(oknardia_priceoffer.id) AS NumOffers,"
f" AVG(oknardia_priceoffer.fOfferPrice) AS priceAVG,"
f" MAX(oknardia_priceoffer.dOfferModify) AS lastUpdate,"
f" MIN(oknardia_priceoffer.dOfferCreate) AS earlyCreation,"
f" oknardia_merchantbrand.*,"
f" oknardia_merchantoffice.*,"
f" oknardia_merchantoffice.id AS idMERCH,"
f" oknardia_setkit.*,"
f" oknardia_setkit.id AS idSET,"
f" oknardia_pvcprofiles.*,"
f" oknardia_pvcprofiles.id AS idPVC,"
f" oknardia_glazing.*, "
f" oknardia_glazing.id AS idGLAZ "
f"FROM oknardia_ouruser"
f" INNER JOIN oknardia_merchantoffice"
f" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id"
f" INNER JOIN oknardia_merchantbrand"
f" ON oknardia_merchantoffice.kMerchantName_id = oknardia_merchantbrand.id"
f" INNER JOIN oknardia_setkit"
f" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
f" INNER JOIN oknardia_priceoffer"
f" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
f" INNER JOIN oknardia_pvcprofiles"
f" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id"
f" INNER JOIN oknardia_glazing"
f" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id "
f"WHERE oknardia_merchantbrand.id = {company_id} "
f"AND oknardia_priceoffer.sOfferActive = TRUE "
f"GROUP BY oknardia_merchantoffice.id,"
f" oknardia_setkit.id,"
f" oknardia_setkit.fSetRating "
f"ORDER BY oknardia_setkit.fSetRating DESC;")
list_sets = list(q_sets)
for i in list_sets:
i.sMerchantMainURL = {"URL": i.sMerchantMainURL,
"URL_VIEW": re.sub(r"(?:^http://|^https://|/$|www\.)", "", i.sMerchantMainURL)}
k = random.randint(1, int(len(i.sOfficeEmails)/2) - 1)
i.sOfficeEmails = [i.sOfficeEmails[0:k], i.sOfficeEmails[k:-k], i.sOfficeEmails[-k:]]
to_template.update({'IMG_FOR_BLOG': i.pMerchantLogo})
i.fSetRating = {"RATING": i.fSetRating,
"STARS": get_rating_set_for_stars(i.fSetRating)}
i.lastUpdate = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.lastUpdate, 'U')))
i.earlyCreation = pytils.dt.distance_of_time_in_words(int(django.utils.dateformat.format(i.earlyCreation, 'U')))
i.sProfileName = {"NAME": i.sProfileName,
"NAME_T": pytils.translit.slugify(i.sProfileName)}
i.sProfileManufacturer = {"NAME": i.sProfileManufacturer,
"NAME_T": pytils.translit.slugify(i.sProfileManufacturer)}
i.fProfileSeals = pytils.numeral.sum_string(i.fProfileSeals, pytils.numeral.MALE, u"контур, контура, контуров")
if i.sSetImplementCatch.lower() in list_not:
i.sSetImplementCatch = ""
if i.sSetClimateControl.lower() in list_not:
i.sSetClimateControl = ""
if len(i.sProfileReinforcement) > 0:
i.sProfileReinforcement = i.sProfileReinforcement[0].lower()+i.sProfileReinforcement[1:]
if len(i.sSetSill) > 0:
i.sSetSill = i.sSetSill[0].lower()+i.sSetSill[1:]
if len(i.sSetPanes) > 0:
i.sSetPanes = i.sSetPanes[0].lower()+i.sSetPanes[1:]
if len(i.sSetSlope) > 0:
i.sSetSlope = i.sSetSlope[0].lower()+i.sSetSlope[1:]
if len(i.sSetUninstallInstall) > 0:
i.sSetUninstallInstall = i.sSetUninstallInstall[0].lower()+i.sSetUninstallInstall[1:]
if len(i.sSetDelivery) > 0:
i.sSetDelivery = i.sSetDelivery[0].lower()+i.sSetDelivery[1:]
if len(i.sSetOtherConditions) > 0:
i.sSetOtherConditions = i.sSetOtherConditions[0].lower()+i.sSetOtherConditions[1:]
to_template.update({
'SETS': list_sets,
# получаем последние визиты клиента через куки
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "catalog/catalog_company_detail.html", to_template)
+82
View File
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import HttpRequest, HttpResponse
from oknardia.models import (
Seria_Info,
Win_MountDim,
)
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
from web.add_func import get_flaps_for_mini_pictures
import time
import pytils
def standard_opening(request: HttpRequest) -> HttpResponse:
time_start = time.perf_counter()
to_template = {} # словарь, для передачи шаблону
q_seria = Seria_Info.objects.raw('SELECT oknardia_seria_info.id, oknardia_seria_info.sName '
'FROM oknardia_seria_info '
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
'ORDER BY oknardia_seria_info.sName;')
to_template.update({'SERIAS': list(q_seria)})
q_win_opening = Win_MountDim.objects.raw(
'SELECT oknardia_win_mountdim.*,'
' oknardia_seria_info.sName,'
' oknardia_seria_info.id AS ID_Seria '
'FROM oknardia_win_mountdim'
' INNER JOIN oknardia_mountdim2apartment'
' ON oknardia_win_mountdim.id = oknardia_mountdim2apartment.kMountDim_id'
' RIGHT OUTER JOIN oknardia_apartment_type'
' ON oknardia_apartment_type.id = oknardia_mountdim2apartment.kApartment_id'
' RIGHT OUTER JOIN oknardia_seria_info'
' ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.id '
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
'GROUP BY oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,'
' oknardia_win_mountdim.bIsDoor, oknardia_win_mountdim.bIsNearDoor,'
' oknardia_win_mountdim.sFlapConfig, oknardia_win_mountdim.id,'
' oknardia_seria_info.sName, oknardia_seria_info.id '
'ORDER BY oknardia_win_mountdim.iWinWidth DESC,'
' oknardia_win_mountdim.iWinHight DESC,'
' oknardia_win_mountdim.bIsNearDoor,'
' oknardia_win_mountdim.bIsDoor,'
' oknardia_win_mountdim.id,'
' oknardia_seria_info.sName;')
list_windows_opening = []
tmp_id = 0
for i in q_win_opening:
if tmp_id != i.id:
tmp_id = i.id
image_file_name = get_flaps_for_mini_pictures(i.sFlapConfig)
list_windows_opening.append({
"ID": i.id,
"INCLUDING_IN_SERIA": [{
"ID": i.ID_Seria,
"NAME_T": pytils.translit.slugify(i.sName),
"NAME": i.sName
}],
"INCLUDING_IN_SERIA_ID": [],
"URL2IMG": image_file_name,
"FLAP_CONFIG": i.sFlapConfig,
"DESCRIPTION": i.sDescripion.split(" для")[0].split(" (")[0],
"DESCRIPTION_L": i.sDescripion,
"IS_DOOR": i.bIsDoor,
"IS_NEAR_DOOR": i.bIsNearDoor,
"H": i.iWinHight * 10,
"W": i.iWinWidth * 10
})
else:
list_windows_opening[-1]["INCLUDING_IN_SERIA"].append({
"ID": i.ID_Seria,
"NAME_T": pytils.translit.slugify(i.sName),
"NAME": i.sName
})
to_template.update({
'LIST_WIN_OPENING': list_windows_opening,
# получаем последние визиты клиента через куки
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "catalog/catalog_standard_opening.html", to_template)
+356
View File
@@ -0,0 +1,356 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Count
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse
from oknardia.settings import *
from oknardia.models import Catalog2Profile, PVCprofiles, PriceOffer
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
from web.add_func import normalize, get_rating_set_for_stars
import time
import json
import re
import pytils
# ---------------------------------------------------------------------------
# Модульные хелперы, общие для всех вьюх этого файла
# ---------------------------------------------------------------------------
def make_slug(value: str) -> str:
"""Транслитерирует строку в slug (pytils)."""
return pytils.translit.slugify(value).lower()
def _merchant_row_to_dict(row: dict) -> dict:
"""Преобразует ORM-строку с данными партнёра в словарь для шаблона."""
merchant_name = row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName"]
return {
"MERCHANT_ID": row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id"],
"MERCHANT_NAME": merchant_name,
"MERCHANT_NAME_T": make_slug(merchant_name),
"MERCHANT_LOGO_URL": row["kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo"],
"MERCHANT_OFFERS": row["offers_by_merchant"],
}
def _profile_row_to_dict(profile: dict) -> dict:
"""Преобразует ORM-строку профиля в словарь для шаблона."""
return {
"PROFILE_NAME": profile["sProfileBriefDescription"],
"PROFILE_ID": profile["id"],
"PROFILE_URL": make_slug(profile["sProfileName"]),
"PROFILE_RATING": profile["fProfileRating"],
"PROFILE_RATING_STARS": get_rating_set_for_stars(profile["fProfileRating"]),
}
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
to_template.update({
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start),
})
# ---------------------------------------------------------------------------
def catalog_profile(request: HttpRequest) -> HttpResponse:
"""
КАТАЛОГ ПРОФИЛЕЙ: страница со списком производителей и моделей (марками) профилей
:param request: HttpRequest -- входящий http-запрос
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.perf_counter()
# Берём только те поля, которые реально нужны для построения страницы каталога.
# Это позволяет не тащить лишние данные из БД и сразу работать с простыми словарями.
profile_rows = list(
PVCprofiles.objects.values(
"id",
"sProfileName",
"sProfileBriefDescription",
"sProfileManufacturer",
).order_by("sProfileManufacturer", "sProfileBriefDescription")
)
profile_count = len(profile_rows)
# В этом контексте смешанные типы значений (str/int/list/float), поэтому задаём общий тип явно.
to_template: dict[str, object] = {
'CATALOG_PROFILE_NUM': pytils.numeral.get_plural(profile_count, "профиль,профиля,профилей")
}
list_profile_manufactures = []
tmp_profile_manufacture = ""
for profile in profile_rows:
if profile["sProfileManufacturer"] == "":
# Пустой производитель в каталоге только мешает: не создаём для него отдельную группу.
continue
if tmp_profile_manufacture != profile["sProfileManufacturer"]:
# Новый производитель — открываем новую группу карточек.
tmp_profile_manufacture = profile["sProfileManufacturer"]
list_profile_manufactures.append({
"PROF_MAN_ID": profile["id"],
"PROF_MAN": profile["sProfileManufacturer"],
"PROF_MAN_T": make_slug(profile["sProfileManufacturer"]),
"PROF_MAN_LIST": [{
"PROF_NAME_ID": profile["id"],
"PROF_NAME": profile["sProfileBriefDescription"],
"PROF_NAME_T": make_slug(profile["sProfileName"]),
}]
})
else:
# Если производитель уже встречался, просто дописываем новую модель в его список.
list_profile_manufactures[-1]["PROF_MAN_LIST"].append({
"PROF_NAME_ID": profile["id"],
"PROF_NAME": profile["sProfileBriefDescription"],
"PROF_NAME_T": make_slug(profile["sProfileName"]),
})
to_template.update({
'CATALOG_PROFILE_MAN1_NAME2': list_profile_manufactures,
'CATALOG_MANUFACT_NUM': len(list_profile_manufactures),
'CATALOG_MANUFACT_NUM_W':
pytils.numeral.sum_string(len(list_profile_manufactures), pytils.numeral.MALE, ("производитель",
"производителя",
"производителей")),
})
_append_visit_context(to_template, request, time_start)
return render(request, "catalog/catalog_of_profiles.html", to_template)
def catalog_profile_model(request: HttpRequest, manufacture_id: int, manufacture_name: str,
model_id: int, model_name: str) -> HttpResponse:
"""
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием марки профиля
:param request: HttpRequest -- входящий http-запрос
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
:param model_id: id модели (марки) профиля
:param model_name: модель (марка) профиля (транслитерированное pytils.translit.slugify(sProfileName))
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.perf_counter()
manufacture_id = int(manufacture_id)
model_id = int(model_id)
q_pvc_by_id = PVCprofiles.objects.get(id=model_id)
manufacturer_slug = pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)
model_slug = pytils.translit.slugify(q_pvc_by_id.sProfileName)
if manufacturer_slug != manufacture_name \
or model_slug != model_name \
or manufacture_id != model_id:
return redirect(f"/catalog/profile/{model_id}-{manufacturer_slug}/"
f"{model_id}-{model_slug}")
# Локальные помощники держат вьюху короче и не размазывают однотипную логику по коду.
def build_other_list(value: str) -> list[str]:
# Убираем пустые куски, чтобы не плодить «пустые» характеристики в шаблоне.
result = []
for chunk in (part.strip() for part in value.split(";")):
if not chunk:
continue
if ":" in chunk:
head, tail = chunk.split(":", 1)
result.append(f"<b>{head.strip()}:</b>{tail.strip()}")
else:
result.append(f"<b>{chunk}</b>")
return result
def update_pub_dat(current_pub_dat: datetime | None, candidate_pub_dat: datetime | None) -> datetime | None:
# На странице оставляем дату публикации/обновления только если она реально новее карточки профиля.
if candidate_pub_dat is None:
return current_pub_dat
if current_pub_dat is None or candidate_pub_dat.replace(tzinfo=None) > current_pub_dat.replace(tzinfo=None):
return candidate_pub_dat
return current_pub_dat
def apply_rating_colors(rating: dict, rating_pairs: tuple[tuple[str, str], ...], multiplier: int,
gray: bool = False) -> None:
# Один маленький helper вместо россыпи почти одинаковых строк: меняется только множитель и формат RGB.
for rating_key, template_key in rating_pairs:
color = int(255 - rating[rating_key] * multiplier)
if gray:
to_template[template_key] = f"{color},{color},{color}"
else:
to_template[template_key] = f"{color},255,{color}"
to_template: dict[str, object] = {"CATALOG_MODEL": q_pvc_by_id,
"CATALOG_MAN2URL": manufacture_name,
"CATALOG_URL": f"{manufacture_id}-{manufacture_name}",
"CATALOG_URL2": f"{manufacture_id}-{manufacture_name}/{model_id}-{model_name}",
"PROFILE_RATING_STARS": get_rating_set_for_stars(q_pvc_by_id.fProfileRating)}
try:
got_json = json.loads(q_pvc_by_id.sProfileDescription)
# раскрашиваем кружочки рейтинга напротив характеристик профиля
rating_pairs = (
(RANK_PVCP_CAMERAS_NUM_NAME, "RANK_PVCP_CAMERAS_COLOR"),
(RANK_PVCP_SEALS_NAME, "RANK_PVCP_SEALS_COLOR"),
(RANK_PVCP_THICKNESS_NAME, "RANK_PVCP_THICKNESS_COLOR"),
(RANK_PVCP_G_THICKNESS_NAME, "RANK_PVCP_G_THICKNESS_COLOR"),
(RANK_PVCP_RABBET_NAME, "RANK_PVCP_RABBET_COLOR"),
(RANK_PVCP_HEAT_TRANSFER_NAME, "RANK_PVCP_HEAT_TRANSFER_COLOR"),
(RANK_PVCP_SOUNDPROOFING_NAME, "RANK_PVCP_SOUNDPROOFING_COLOR"),
(RANK_PVCP_HEIGHT_NAME, "RANK_PVCP_HEIGHT_COLOR"),
)
if KEY_RATING in got_json:
# кружочки зелёные
apply_rating_colors(got_json[KEY_RATING], rating_pairs, 255)
elif KEY_RATING_VIRTUAL in got_json:
# кружочки серые
apply_rating_colors(got_json[KEY_RATING_VIRTUAL], rating_pairs, 64, gray=True)
else:
pass
if KEY_HTML in got_json:
to_template.update({"EXTRA_INFO": got_json[KEY_HTML]})
except (TypeError, ValueError, KeyError):
pass
to_template.update({"LIST_OTHER": build_other_list(q_pvc_by_id.sProfileOther)})
# Партнёров считаем через ORM: так код проще читать и легче переносить между СУБД.
q_merchant = (
PriceOffer.objects.filter(
kOffer2SetKit__kSet2PVCprofiles_id=model_id,
sOfferActive=True,
)
.values(
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id",
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo",
)
.annotate(offers_by_merchant=Count("id"))
.order_by("-offers_by_merchant", "kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName")
)
to_template.update({'MERCHANTS': [_merchant_row_to_dict(row) for row in q_merchant]})
# Близкие профили этого же производителя нужны для быстрых переходов по карточкам.
q_profiles = (
PVCprofiles.objects.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer)
.exclude(id=model_id)
.values("id", "fProfileRating", "sProfileBriefDescription", "sProfileName")
.order_by("fProfileRating")
)
to_template.update({'PROFILES': [_profile_row_to_dict(profile) for profile in q_profiles]})
# Описание профиля берём через связку каталог -> блог: это один ORM-запрос вместо сырого SQL.
q_profiles_detail = (
Catalog2Profile.objects.filter(
kProfile_id=model_id,
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MODEL,
kBlogCatalog__isnull=False,
)
.select_related("kBlogCatalog")
.order_by("kBlogCatalog__iCatalogSort")
)
profile_blog_posts = [row.kBlogCatalog for row in q_profiles_detail if row.kBlogCatalog is not None]
to_template.update({'PROFILE_DETAIL': profile_blog_posts})
# Картинка и дата публикации для meta-тегов берутся из связанного блога, если он есть.
if profile_blog_posts:
for blog_post in profile_blog_posts:
if blog_post.sImgForBlogSocial:
to_template['IMG_FOR_BLOG'] = blog_post.sImgForBlogSocial
break
pub_dat: datetime = q_pvc_by_id.dProfileModify
if profile_blog_posts:
profile_blog_dat: datetime | None = max((post.dPostDataModify for post in profile_blog_posts), default=pub_dat)
pub_dat = update_pub_dat(pub_dat, profile_blog_dat) or pub_dat
to_template['PUB_DAT'] = pub_dat
_append_visit_context(to_template, request, time_start)
return render(request, "catalog/catalog_of_profiles_model.html", to_template)
def catalog_profile_manufacture(request: HttpRequest, manufacture_id: int, manufacture_name: str) -> HttpResponse:
"""
КАТАЛОГ ПРОФИЛЕЙ: страница с описанием производителя профилей и списком марки производимых им профилей
:param request: HttpRequest -- входящий http-запрос
:param manufacture_id: id профиля. Предполагается, что это первый id при сортировке по sProfileBriefDescription
:param manufacture_name: название производителя (транслитерированное pytils.translit.slugify())
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.perf_counter()
manufacture_id = int(manufacture_id)
q_pvc_by_id = PVCprofiles.objects.get(id=manufacture_id)
if pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer) != manufacture_name:
return redirect(f'/catalog/profile/{manufacture_id}-'
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
else:
q_pvc_by_id = PVCprofiles.objects.order_by('id') \
.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer).first()
if q_pvc_by_id.id != manufacture_id:
return redirect(f'/catalog/profile/{q_pvc_by_id.id}-'
f'{pytils.translit.slugify(q_pvc_by_id.sProfileManufacturer)}')
to_template: dict[str, object] = {'CATALOG_MANUFACT': q_pvc_by_id.sProfileManufacturer,
'CATALOG_MAN2URL': manufacture_name,
'CATALOG_URL': f"{manufacture_id}-{manufacture_name}"}
try:
# Получаем статью-описание производителя через Catalog2Profile → BlogPosts.
# GROUP BY из оригинального SQL здесь не нужен: нас устраивает любая первая запись.
catalog_entry = (
Catalog2Profile.objects.filter(
kProfile__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MANUFACTURER,
kBlogCatalog__bCatalog=True,
)
.select_related("kBlogCatalog")
.first()
)
if catalog_entry is None or catalog_entry.kBlogCatalog is None:
raise ObjectDoesNotExist
manufacture_description = catalog_entry.kBlogCatalog
to_template.update({'PUB_DAT': manufacture_description.dPostDataModify})
if PATH_FOR_IMG_BLOG in (manufacture_description.sImgForBlogSocial or ""):
to_template.update({'IMG_FOR_BLOG': manufacture_description.sImgForBlogSocial})
content = re.sub(r'<cut[\s\S]*>', '', manufacture_description.sPostContent, 0, re.IGNORECASE)
to_template.update({'HEADER': manufacture_description.sPostHeader, 'CONTENT': content})
to_template.update({'TIZER': re.sub(
r'<script[\s\S]*?</script>|<style[\s\S]*?</style>|<iframe[\s\S]*?</iframe>',
'', content, 0, re.IGNORECASE,
)})
except (ObjectDoesNotExist, IndexError, TypeError, KeyError):
pass
# Список всех профилей этого производителя для навигации по карточкам.
q_profiles = (
PVCprofiles.objects.filter(sProfileManufacturer=q_pvc_by_id.sProfileManufacturer)
.values("id", "fProfileRating", "sProfileBriefDescription", "sProfileName")
.order_by("fProfileRating")
)
to_template.update({'PROFILES': [_profile_row_to_dict(p) for p in q_profiles]})
try:
# Доля предложений этого производителя относительно всех предложений в базе.
offers_by_manufacture = PriceOffer.objects.filter(
kOffer2SetKit__kSet2PVCprofiles__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
).count()
total_offers = PriceOffer.objects.count()
offers_other = total_offers - offers_by_manufacture
to_template.update({
'OFFERS_BY_MAUFACTURE': offers_by_manufacture,
'OFFERS_OTHER': offers_other,
'OFFERS_ANGLE': 90 + 180 * normalize(offers_by_manufacture, total_offers),
})
if offers_by_manufacture > 0:
# Партнёры, у которых есть предложения с профилями этого производителя.
q_merchant = (
PriceOffer.objects.filter(
kOffer2SetKit__kSet2PVCprofiles__sProfileManufacturer=q_pvc_by_id.sProfileManufacturer,
)
.values(
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__id",
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__pMerchantLogo",
)
.annotate(offers_by_merchant=Count("id"))
.order_by(
"-offers_by_merchant",
"kOffer2SetKit__kSet2User__kMerchantOffice__kMerchantName__sMerchantName",
)
)
to_template.update({'MERCHANTS': [_merchant_row_to_dict(row) for row in q_merchant]})
except (ObjectDoesNotExist, IndexError, TypeError):
pass
_append_visit_context(to_template, request, time_start)
return render(request, "catalog/catalog_of_profiles_manufacture.html", to_template)
+404
View File
@@ -0,0 +1,404 @@
# -*- coding: utf-8 -*-
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse
from django.template.loader import render_to_string
from oknardia.settings import *
from oknardia.models import (
Seria_Info,
Win_MountDim,
Building_Info,
)
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
from web.add_func import get_flaps_for_big_pictures, touch_reload_wsgi
import time
import os
import math
import pytils
# Каталог типовых серий зданий (пока переадресация)
def catalog_seria(request: HttpRequest) -> HttpResponse:
"""
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница со всеми сериями зданий в базе окнардии
:param request: HttpRequest -- входящий http-запрос
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.perf_counter()
try:
q_seria = Seria_Info.objects.raw('SELECT'
' oknardia_seria_info.id,'
' oknardia_seria_info.sURL2IMG,'
' oknardia_seria_info.sName '
'FROM oknardia_seria_info '
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
'ORDER BY oknardia_seria_info.sName;')
list_seria = []
for i in q_seria:
list_seria.append({
"ID": i.id,
"URL": i.sURL2IMG,
"NAME": i.sName,
"NAME_T": pytils.translit.slugify(i.sName)
})
to_template = {'SERIAS': list_seria}
except (ObjectDoesNotExist,):
to_template = {}
to_template.update({
# получаем последние визиты клиента через куки
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "catalog/catalog_seria.html", to_template)
def catalog_seria_info(request: HttpRequest, seria_name_translit: None, seria_id: int = 843) -> HttpResponse:
"""
КАТАЛОГ ТИПОВЫЙ СЕРИЙ: страница детальной информацией по серии зданий
:param request: HttpRequest -- входящий http-запрос
:param seria_name_translit: str -- имя серии здания (транслитерированное pytils.translit.slugify())
:param seria_id: int -- id серии
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.perf_counter()
msg = ""
try:
seria_id = int(seria_id)
q_seria = Seria_Info.objects.get(id=seria_id)
if q_seria.id != q_seria.kRoot_id or seria_name_translit != pytils.translit.slugify(q_seria.sName):
return redirect(f"/catalog/seria/{pytils.translit.slugify(q_seria.sName)}/all{seria_id}")
except(ObjectDoesNotExist, ValueError,):
return redirect("/catalog/")
# если есть "облегченный" шаблон с частичным пре-рендером, то используем его.
light_template = f"{PATH_FOR_SERIA_INFO_HTML_INCLUDE}{str(seria_id)}_id.html"
light_template_w_path = f"{TEMPLATES[0]['DIRS'][0]}/{light_template}"
# print(f"{TEMPLATES[0]['DIRS'][0]}/{light_template}")
# print(light_template_w_path)
# print(light_template_w_path)
if os.path.isfile(light_template_w_path):
is_hard_template = False
else:
is_hard_template = True
to_template = {}
# получаем проемы использующиеся в данной серии домов
q_windows_in_seria = Win_MountDim.objects.raw(
f"SELECT DISTINCT"
f" oknardia_win_mountdim.iWinWidth, oknardia_win_mountdim.iWinHight,"
f" oknardia_win_mountdim.sDescripion, oknardia_win_mountdim.bIsDoor,"
f" oknardia_win_mountdim.bIsNearDoor, oknardia_win_mountdim.sFlapConfig,"
f" oknardia_win_mountdim.iWinDepth, oknardia_win_mountdim.id,"
f" 1 AS iQuantity "
f"FROM oknardia_mountdim2apartment"
f" INNER JOIN oknardia_win_mountdim"
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
f" INNER JOIN oknardia_apartment_type"
f" ON oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id "
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id}"
f" ORDER BY oknardia_win_mountdim.bIsNearDoor DESC,"
f" oknardia_win_mountdim.bIsDoor DESC,"
f" oknardia_win_mountdim.iWinWidth,"
f" oknardia_win_mountdim.iWinHight DESC;")
if is_hard_template:
# Получаем данные для отрисовки больших картинок с проёмами и передаём в "тяжёлый" шаблон
to_template.update(get_flaps_for_big_pictures(q_windows_in_seria))
# формируем строку для включения в SQL-запрос вида "(2,8,16,46,1)"
str_for_sql_in = "("
for count in q_windows_in_seria:
str_for_sql_in += str(count.id) + ","
str_for_sql_in = str_for_sql_in[:-1] + ")"
# print StringForSqlIN
# Получаем данные для таблички Окон по типам квартирах в серии дома
# " IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity," \
# tStart2 = time.perf_counter() # замер времени
q_win_in_apartment_in_seria = Win_MountDim.objects.raw(
f"SELECT"
f" oknardia_win_mountdim.id,"
f" oknardia_apartment_type.sNameApartment,"
f" oknardia_win_mountdim.iWinWidth,"
f" oknardia_win_mountdim.iWinHight,"
f" oknardia_apartment_type.id AS id_apart,"
f" IFNULL(oknardia_mountdim2apartment.iQuantity, 0) AS iQuantity,"
f" COUNT(oknardia_priceoffer.id) AS NumOffers "
f"FROM oknardia_apartment_type"
f" INNER JOIN oknardia_win_mountdim"
f" LEFT OUTER JOIN oknardia_mountdim2apartment"
f" ON oknardia_mountdim2apartment.kMountDim_id = oknardia_win_mountdim.id"
f" AND oknardia_mountdim2apartment.kApartment_id = oknardia_apartment_type.id"
f" LEFT OUTER JOIN oknardia_priceoffer"
f" ON oknardia_priceoffer.kOffer2MountDim_id = oknardia_win_mountdim.id"
f" LEFT OUTER JOIN oknardia_ouruser"
f" ON oknardia_ouruser.id = oknardia_priceoffer.kOfferFromUser_id "
f"WHERE oknardia_apartment_type.kSeria_id = {seria_id} "
f"AND oknardia_win_mountdim.id IN {str_for_sql_in} "
f"GROUP BY oknardia_apartment_type.id,"
f" oknardia_apartment_type.sNameApartment,"
f" oknardia_win_mountdim.id,"
f" oknardia_mountdim2apartment.iQuantity "
f"ORDER BY oknardia_apartment_type.iSort,"
f" oknardia_win_mountdim.bIsNearDoor DESC,"
f" oknardia_win_mountdim.bIsDoor DESC,"
f" oknardia_win_mountdim.iWinWidth,"
f" oknardia_win_mountdim.iWinHight DESC;")
list_win_in_seria = list(q_windows_in_seria)
total_column = len(list_win_in_seria) - 1
count_column = 0
min_offer_in_row = 1000000000
table_of_win_in_seria_by_apartmment = []
row_for_table = []
offer_and_merchant_per_win = [
{
"WIN_OFFER": 0,
"WIN_MERCHANT": 0,
"WIN_W": list_win_in_seria[i].iWinWidth,
"WIN_H": list_win_in_seria[i].iWinHight,
"WIN_ID": list_win_in_seria[i].id
} for i in range(total_column + 1)]
for count in q_win_in_apartment_in_seria:
if count.iQuantity != 0:
row_for_table.append({
"WIN_NUM": [chr(65 + count_column)],
"WIN_Q": count.iQuantity,
"WIN_ID": count.id,
"WIN_WIDTH": list_win_in_seria[count_column].iWinWidth,
"WIN_HEIGHT": list_win_in_seria[count_column].iWinHight,
"WIN_DESCRIPTION": list_win_in_seria[count_column].sDescripion,
"WIN_FLAPCFG": list_win_in_seria[count_column].sFlapConfig
})
if min_offer_in_row > count.NumOffers:
min_offer_in_row = count.NumOffers
if offer_and_merchant_per_win[count_column]["WIN_OFFER"] < count.NumOffers:
offer_and_merchant_per_win[count_column]["WIN_OFFER"] = count.NumOffers
else:
row_for_table.append({"WIN_NUM": ""})
if count_column < total_column:
count_column += 1
else:
# print row_for_table
table_of_win_in_seria_by_apartmment.append({"WIN_IN_APART": row_for_table,
"APART_NAME": count.sNameApartment,
"APART_ID": count.id_apart,
"NUM_OFFERS": min_offer_in_row})
count_column = 0
min_offer_in_row = 10000
row_for_table = []
# print(table_of_win_in_seria_by_apartmment)
# print(f"==============>{float(time.perf_counter()-tStart2)}<==============")
# print NumOffersPerColumn, NumMerchantPerColumn
to_template.update({"WIN_OFFER_AND_MERCHANT": offer_and_merchant_per_win,
"TABLE_OF_WINDOWS": table_of_win_in_seria_by_apartmment})
# для "тяжелого шаблона" получаем навигацию страницы, данные для карты и графика ввода в эксплуатацию
if is_hard_template:
# если вызывается "тяжелый" шаблон, то нужно подготовить тяжелые данные для построения навигации
seria_id, for_seria_nav = seria_nav(seria_id)
to_template.update(for_seria_nav) # данные для навигации по сериям
to_template.update(seria_info_year(seria_id)) # данные для графика ввода зданий серии в эксплуатацию
to_template.update(seria_info_geo_code(seria_id)) # данные для карты
# т.к. обрабатывается "тяжелый шаблон" надо создать "легкий шаблон"
# для его использования в будущем.
string_prerender = render_to_string("seria_info/all_seria_info_pre_light.html", to_template)
file = open(light_template_w_path, 'w')
# file.write(AA.encode('utf-8'))
file.write(string_prerender)
file.close()
touch_reload_wsgi(light_template_w_path)
else:
seria_name = Seria_Info.objects.get(id=seria_id).sName
to_template.update({'THIS_SERIA_NAME': seria_name})
# to_template.update({'LOG_VISIT': GetLastAllUserVisitSeriaList(SeriaName),
# 'ticks': float(time.perf_counter()-time_start)})
to_template.update({
# получаем последние визиты клиента через куки
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.perf_counter() - time_start)
})
return render(request, light_template, to_template)
def seria_nav(seria_id: int = 12) -> (int, dict):
"""
Возвращает корректный seria_id и кортеж для построения навигации по сериям дома
:param seria_id: id серии
:return:
"""
q_seria = Seria_Info.objects.raw(
'SELECT oknardia_seria_info.id,'
' oknardia_seria_info.sName,'
' oknardia_seria_info.sSeriaDescription,'
' oknardia_seria_info.kRoot_id,'
' oknardia_seria_info.kParent_id '
'FROM oknardia_seria_info '
'WHERE oknardia_seria_info.id = oknardia_seria_info.kRoot_id '
'ORDER BY oknardia_seria_info.sName;')
error_seria = True
for count_seria in q_seria:
if count_seria.id == int(seria_id):
error_seria = False
break
if error_seria:
# Ошибочный seria_id. Такой базовой серии нет и надо ее найти.
try:
query = Seria_Info.objects.get(id=int(seria_id))
if query.kRoot_id is not None:
# базовая серия прописана в kRoot_id
seria_id = query.kRoot_id
else:
# == корневой нет
# == ищем методом наименьших расстояний"
min_min = 100000000
min_id = seria_id
for count_seria in q_seria:
if math.fabs(int(seria_id) - count_seria.id) < min_min:
min_min = math.fabs(int(seria_id) - count_seria.id)
min_id = count_seria.id
seria_id = min_id
except ObjectDoesNotExist:
seria_id = q_seria[0].id
# print(f"-->{seria_id}<--")
return all_seria_nav(seria_id, q_seria)
def all_seria_nav(seria_id: int, q_seria) -> (int, dict):
seria_nav_dim = []
this_return = {}
for count_seria in q_seria:
one_seria = {}
one_seria.update({"SERIA_R": count_seria.sName, "ID2URL": count_seria.id})
if count_seria.id == seria_id:
this_return.update({"THIS_SERIA_NAME": count_seria.sName,
"THIS_SERIA_DESCRIPTION": count_seria.sSeriaDescription})
# one_seria.update({"SERIA_L": ""})
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
else:
one_seria.update({"SERIA_L": pytils.translit.slugify(count_seria.sName)})
seria_nav_dim.append(one_seria)
this_return.update({"SERIA_NAV_DIM": seria_nav_dim})
return seria_id, this_return
def seria_info_year(seria_id: int = 12) -> dict:
""" Возвращает данные для графика распределения сдачи серии в эксплуатацию
:param seria_id: int -- id серии для которой нужно получить данные
:return: dict -- данные для графика распределения сдачи серии в эксплуатацию типа:
{"DATA4GRAPH": [{'YEAR': 1997, 'NUMS': 1, 'CLRS': '99'},
{'YEAR': 1998, 'NUMS': 15, 'CLRS': 'сс'},
{'YEAR': 1998, 'NUMS': 10, 'CLRS': 'a9'}
]
}
"""
seria_in_years = []
query = Seria_Info.objects.raw(
f"SELECT oknardia_building_info.iCommissioning_year as id,"
f" COUNT(oknardia_building_info.iCommissioning_year) AS NumInYear "
f"FROM oknardia_building_info"
f" INNER JOIN oknardia_seria_info"
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
f"WHERE oknardia_seria_info.kRoot_id = {seria_id} "
f"GROUP BY oknardia_building_info.iCommissioning_year;"
)
max_per_year = 0
graph_color_light = 0xCC # самый светлый цвет на графике (максимальное значение)
graph_color_dark = 0x99 # самый темный цвет на графике (минимальное значение)
for YearCount in query:
if int(YearCount.NumInYear) > max_per_year:
max_per_year = int(YearCount.NumInYear)
# print("max", MaxPerYear)
for YearCount in query:
data_of_year = {}
try:
data_of_year.update({
"YEAR": int(YearCount.id),
"NUMS": YearCount.NumInYear,
"CLRS": str(hex(int(graph_color_dark + YearCount.NumInYear * (
graph_color_light - graph_color_dark) / max_per_year)))[2:]
})
except ValueError:
continue
seria_in_years.append(data_of_year)
# print(seria_in_years)
return {"DATA4GRAPH": seria_in_years}
def seria_info_geo_code(seria_id: str = '12') -> dict:
""" Возвращает массив геокоординат зданий одной серии
:param seria_id: str -- id серии для которой нужно получить данные
:return: dict -- массив геокоординат зданий серии
"""
data_return = {}
seria_to_geo = []
municipal_m2 = 0 # муниципальный фонд (кв.м)
residential_m2 = 0 # жилой фонд (кв.м)
government_m2 = 0 # государственные учреждения занимают (кв.м.)
residents = 0 # количество жильцов
apartments = 0 # число квартиры
accounts = 0 # количество лицевых счетов
condition_max = 0 # максимальное значение показателя состояния здания
condition_min = 1000000 # минимальное значение показателя состояния здания
query = Building_Info.objects.raw(
f"SELECT"
f" oknardia_building_info.id,"
f" oknardia_seria_info.kRoot_id as SerId,"
f" oknardia_building_info.sAddress,"
f" oknardia_building_info.fResidential_Area,"
f" oknardia_building_info.fMunicipal_Area,"
f" oknardia_building_info.fGovernment_Area,"
f" oknardia_building_info.iNum_Residents,"
f" oknardia_building_info.iNum_Apartments,"
f" oknardia_building_info.iNum_Accounts,"
f" oknardia_building_info.fCondition_House,"
f" oknardia_building_info.fGeoCode_Latitude,"
f" oknardia_building_info.fGeoCode_Longitude "
f"FROM oknardia_building_info"
f" INNER JOIN oknardia_seria_info"
f" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id "
f"WHERE oknardia_seria_info.kRoot_id IN ({seria_id});"
)
for count in query:
if int(count.fGeoCode_Latitude) != 0 and int(count.fGeoCode_Longitude) != 0:
seria_to_geo.append({"LATITUDE": count.fGeoCode_Latitude,
"LONGITUDE": count.fGeoCode_Longitude,
"ADDR_ID": count.id,
"ADDR_LAT": pytils.translit.slugify(count.sAddress),
"ADDR_RUS": count.sAddress,
"SER_ID": count.SerId
})
if count.fMunicipal_Area > 0:
municipal_m2 += count.fMunicipal_Area
if count.fResidential_Area > 0:
residential_m2 += count.fResidential_Area
if count.fGovernment_Area > 0:
government_m2 += count.fGovernment_Area
if count.iNum_Residents > 0:
residents += count.iNum_Residents
if count.iNum_Residents > 0:
residents += count.iNum_Residents
if count.iNum_Apartments > 0:
apartments += count.iNum_Apartments
if count.iNum_Accounts > 0:
accounts += count.iNum_Accounts
if count.fCondition_House > 0:
if count.fCondition_House > condition_max:
condition_max = count.fCondition_House
if count.fCondition_House < condition_min:
condition_min = count.fCondition_House
data_return.update({"DATA4GEO": seria_to_geo,
"MUNICIPAL_M2": municipal_m2,
"RESIDENTIAL_M2": residential_m2,
"GOVERNMENT_M2": government_m2,
"RESIDENTS": residents,
"APARTMENTS": apartments,
"ACCOUNTS": accounts,
"CONDITION_MAX": condition_max,
"CONDITION_MIN": condition_min})
# print(seria_to_geo)
return data_return
View File
+1 -1
View File
@@ -5,7 +5,7 @@ from django.core.exceptions import ObjectDoesNotExist
from time import time
from oknardia.settings import *
from oknardia.models import Seria_Info
from web.catalog import all_seria_nav
from web.catalog_series import all_seria_nav
# from oknardia.catalog import all_seria_nav
import math
import os
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
@@ -0,0 +1,612 @@
# -*- coding: utf-8 -*-
from __future__ import annotations
"""
Команда генерации sitemap-файлов проекта.
Почему реализовано именно так:
- Генерация выполняется оффлайн (через management command), чтобы не нагружать веб-запросы.
- На выходе всегда создаются статические XML-файлы, которые потом отдает Nginx/прокси.
- URL-источники описаны через Django Sitemap API (классы Sitemap), но рендер XML
контролируем самостоятельно для точного управления лимитами размера/количества.
"""
from collections import defaultdict
from dataclasses import dataclass
from datetime import date, datetime
from itertools import combinations
from pathlib import Path
from typing import Iterable
from xml.etree import ElementTree as ET
from django.conf import settings
from django.contrib.sitemaps import Sitemap
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Count, F, Max, Min
from django.utils import timezone
from oknardia.models import (
Apartment_Type,
BlogPosts,
Building_Info,
MerchantBrand,
PriceOffer,
PVCprofiles,
Seria_Info,
SetKit,
Win_MountDim,
)
import pytils
# Namespace схемы sitemap.xml по стандарту sitemaps.org.
SITEMAP_XMLNS = "http://www.sitemaps.org/schemas/sitemap/0.9"
@dataclass(slots=True)
class SitemapBuildResult:
"""Итог генерации sitemap для удобного вывода в CLI и web-обертках."""
# Общее число URL, записанных во все sitemap-файлы.
total_urls: int
# Количество созданных файлов (1 = только sitemap.xml, >1 = sitemapindex + sitemapNNNN.xml).
files_count: int
# Время выполнения генерации в секундах.
elapsed_seconds: float
# Физический каталог, куда записаны файлы.
output_dir: Path
def _as_sitemap_date(value: date | datetime | None) -> str:
"""
Приводит дату/время к формату `YYYY-MM-DD`.
Для sitemap нам не нужна точность до секунд: поисковикам достаточно даты.
Если значение не передано, используем текущую локальную дату.
"""
if value is None:
return timezone.localdate().isoformat()
if isinstance(value, datetime):
return value.date().isoformat()
return value.isoformat()
class SingleWindowSitemap(Sitemap):
"""Источник URL для страниц цен одного проёма (/tsena-odnogo-okna/...)."""
changefreq = "weekly"
priority = 0.5
def __init__(self, lastmod_value: datetime):
# Один timestamp на весь прогон: так проще сравнивать выпуски sitemap.
self.lastmod_value = lastmod_value
def items(self):
# Берем только те монтажные размеры, где есть реальные офферы.
# Сортировка по числу офферов повторяет историческую логику из raw SQL.
mount_ids = (
PriceOffer.objects.values("kOffer2MountDim_id")
.annotate(num_offer=Count("id"))
.order_by("num_offer", "kOffer2MountDim_id")
.values_list("kOffer2MountDim_id", flat=True)
)
# Возвращаем сами объекты Win_MountDim, чтобы location() строил URL без доп. запросов.
return Win_MountDim.objects.filter(id__in=mount_ids).only("id", "iWinWidth", "iWinHight")
def location(self, item: Win_MountDim) -> str:
# В БД размеры в см (Decimal с 1 знаком). В URL исторически используются мм,
# поэтому умножаем на 10 и приводим к int.
width_mm = int(float(item.iWinWidth) * 10)
height_mm = int(float(item.iWinHight) * 10)
return f"/tsena-odnogo-okna/{width_mm}x{height_mm}mm/tip{item.id}"
def lastmod(self, item: Win_MountDim) -> datetime:
return self.lastmod_value
class BuildingOffersSitemap(Sitemap):
"""Источник URL для страниц ценовой выдачи по адресам (/{build_id}/{apart_id}/{slug})."""
changefreq = "weekly"
priority = 0.5
def __init__(self, lastmod_value: datetime):
self.lastmod_value = lastmod_value
def items(self):
# Получаем здания только с валидной привязкой к корневой серии.
buildings = list(
Building_Info.objects.filter(kSeria_Link__kRoot__isnull=False)
.select_related("kSeria_Link__kRoot")
.only("id", "sAddress", "kSeria_Link__kRoot")
.order_by("id")
)
# Для каждой корневой серии нужен список типов квартир, чтобы собрать итоговые URL.
root_ids = {
building.kSeria_Link.kRoot_id
for building in buildings
if building.kSeria_Link_id and building.kSeria_Link.kRoot_id
}
apartments_by_root: dict[int, list[int]] = defaultdict(list)
for root_id, apart_id in Apartment_Type.objects.filter(kSeria_id__in=root_ids).values_list("kSeria_id", "id"):
apartments_by_root[root_id].append(apart_id)
# Генерируем декартово произведение: здание x квартиры его корневой серии.
for building in buildings:
root_id = building.kSeria_Link.kRoot_id if building.kSeria_Link_id else None
if not root_id:
continue
for apart_id in apartments_by_root.get(root_id, []):
yield (building.id, apart_id, pytils.translit.slugify(building.sAddress))
def location(self, item: tuple[int, int, str]) -> str:
build_id, apart_id, slug = item
return f"/{build_id}/{apart_id}/{slug}"
def lastmod(self, item: tuple[int, int, str]) -> datetime:
return self.lastmod_value
class CompareOffersSitemap(Sitemap):
"""Источник URL для страниц сравнения наборов (/compare_offers/1,2,3...)."""
# Для compare-страниц изменения редки, поэтому просим роботов не дергать их часто.
changefreq = "monthly"
priority = 0.35
def __init__(self, lastmod_value: datetime, min_depth: int = 2, max_depth: int = 4):
self.lastmod_value = lastmod_value
# Жестко ограничиваем глубину до 2..4, чтобы не получить комбинаторный взрыв.
self.min_depth = max(2, min_depth)
self.max_depth = min(4, max_depth)
def items(self):
# Берем только активные наборы и строим combinations без повторов/перестановок.
set_ids = list(SetKit.objects.filter(sSetActive=True).order_by("id").values_list("id", flat=True))
for depth in range(self.min_depth, self.max_depth + 1):
for combo in combinations(set_ids, depth):
# Формат URL-параметра должен остаться историческим: "1,2,3".
yield ",".join(str(item) for item in combo)
def location(self, item: str) -> str:
return f"/compare_offers/{item}"
def lastmod(self, item: str) -> datetime:
return self.lastmod_value
class StaticPagesSitemap(Sitemap):
"""Набор важных статических/обзорных страниц, которые не требуют отдельной модели."""
def __init__(self, items: list[dict]):
self._items = items
def items(self):
return self._items
def location(self, item: dict) -> str:
return item["loc"]
def lastmod(self, item: dict) -> date | datetime | None:
return item.get("lastmod")
def changefreq(self, item: dict) -> str:
return item.get("changefreq", "weekly")
def priority(self, item: dict) -> float:
return float(item.get("priority", 0.5))
class BlogListSitemap(Sitemap):
"""Страницы пагинации блога: /blog/P0, /blog/P1, ..."""
changefreq = "weekly"
priority = 0.82
def __init__(self, lastmod_value: date | datetime | None):
self.lastmod_value = lastmod_value
def items(self):
posts_qs = BlogPosts.objects.filter(
dPostDataBegin__lte=timezone.now(),
bPublished=True,
bArchive=False,
)
total_posts = posts_qs.count()
if total_posts == 0:
return []
pages_total = (total_posts - 1) // settings.NUM_BLOG_TIZER_IN_PAGE + 1
return list(range(pages_total))
def location(self, item: int) -> str:
return f"/blog/P{item}"
def lastmod(self, item: int) -> date | datetime | None:
return self.lastmod_value
class BlogPostSitemap(Sitemap):
"""Публичные посты блога в каноническом URL без page_back."""
changefreq = "monthly"
priority = 0.90
def items(self):
return BlogPosts.objects.filter(
dPostDataBegin__lte=timezone.now(),
bPublished=True,
bArchive=False,
).only("id", "sPostHeader", "dPostDataModify")
def location(self, item: BlogPosts) -> str:
return f"/blogpost/{item.id}/{pytils.translit.slugify(item.sPostHeader).lower()}"
def lastmod(self, item: BlogPosts) -> date | datetime | None:
return item.dPostDataModify
class ProfileManufactureSitemap(Sitemap):
"""Страницы производителей профилей: /catalog/profile/{id}-{manufacturer}."""
changefreq = "monthly"
priority = 0.92
def items(self):
return list(
PVCprofiles.objects.values("sProfileManufacturer")
.annotate(first_id=Min("id"), lastmod=Max("dProfileModify"))
.order_by("sProfileManufacturer")
)
def location(self, item: dict) -> str:
manufacturer_slug = pytils.translit.slugify(item["sProfileManufacturer"]).lower()
return f"/catalog/profile/{item['first_id']}-{manufacturer_slug}"
def lastmod(self, item: dict) -> date | datetime | None:
return item.get("lastmod")
class ProfileModelSitemap(Sitemap):
"""Карточки конкретных профильных систем."""
changefreq = "monthly"
priority = 0.94
def items(self):
return PVCprofiles.objects.only("id", "sProfileManufacturer", "sProfileName", "dProfileModify")
def location(self, item: PVCprofiles) -> str:
manufacturer_slug = pytils.translit.slugify(item.sProfileManufacturer).lower()
model_slug = pytils.translit.slugify(item.sProfileName).lower()
# Исторически канонический URL использует id модели и в сегменте manufacturer_id, и в segment model_id.
return f"/catalog/profile/{item.id}-{manufacturer_slug}/{item.id}-{model_slug}"
def lastmod(self, item: PVCprofiles) -> date | datetime | None:
return item.dProfileModify
class SeriaDetailSitemap(Sitemap):
"""Страницы типовых серий домов — это одни из самых важных SEO-страниц проекта."""
changefreq = "monthly"
priority = 0.97
def items(self):
return Seria_Info.objects.filter(id__isnull=False, kRoot_id__isnull=False, id=F("kRoot_id")).only(
"id", "sName", "dSeriaInfoModify"
)
def location(self, item: Seria_Info) -> str:
return f"/catalog/seria/{pytils.translit.slugify(item.sName).lower()}/all{item.id}"
def lastmod(self, item: Seria_Info) -> date | datetime | None:
return item.dSeriaInfoModify
class CompanyDetailSitemap(Sitemap):
"""Страницы брендов/производителей оконных компаний."""
changefreq = "monthly"
priority = 0.91
def items(self):
return list(
MerchantBrand.objects.annotate(
last_offer_modify=Max("merchantoffice__ouruser__setkit__priceoffer__dOfferModify"),
last_office_modify=Max("merchantoffice__dOfficeDataModify"),
).only("id", "sMerchantName")
)
def location(self, item: MerchantBrand) -> str:
return f"/catalog/company/{item.id}-{pytils.translit.slugify(item.sMerchantName).lower()}"
def lastmod(self, item: MerchantBrand) -> date | datetime | None:
return getattr(item, "last_offer_modify", None) or getattr(item, "last_office_modify", None)
class SitemapXmlWriter:
"""
Низкоуровневый писатель XML.
Делит URL на несколько файлов по двум условиям:
- число URL в файле;
- приблизительный размер файла в байтах.
Если chunk-файлов больше одного, создается sitemapindex (sitemap.xml),
который перечисляет sitemap0000.xml, sitemap0001.xml и т.д.
"""
def __init__(
self,
output_dir: Path,
public_base_url: str,
max_items: int,
max_file_size: int,
max_files_qty: int,
):
self.output_dir = output_dir
# Публичный URL-префикс для ссылок в sitemapindex.
self.public_base_url = public_base_url.rstrip("/")
self.max_items = max_items
self.max_file_size = max_file_size
self.max_files_qty = max_files_qty
self.total_urls = 0
self.chunk_files: list[str] = []
self.current_urls: list[ET.Element] = []
# Небольшой стартовый запас размера на корневые XML-теги.
self.current_size = 128
def cleanup_old(self) -> None:
# Перед генерацией удаляем старые sitemap*.xml, чтобы не оставить устаревшие куски.
self.output_dir.mkdir(parents=True, exist_ok=True)
for file_path in self.output_dir.glob("sitemap*.xml"):
file_path.unlink(missing_ok=True)
def add_url(self, loc: str, lastmod: datetime, changefreq: str, priority: float) -> None:
# Собираем XML-элемент URL и оцениваем его вклад в размер файла.
url_element = self._build_url_element(loc=loc, lastmod=lastmod, changefreq=changefreq, priority=priority)
url_size = len(ET.tostring(url_element, encoding="utf-8"))
need_flush = False
if self.current_urls:
# Лимиты применяем только если файл уже что-то содержит:
# так мы гарантируем, что хотя бы один URL всегда будет записан.
if len(self.current_urls) >= self.max_items:
need_flush = True
elif self.current_size + url_size > self.max_file_size:
need_flush = True
if need_flush:
self._flush_chunk()
self.current_urls.append(url_element)
self.current_size += url_size
self.total_urls += 1
def finalize(self, generated_at: datetime) -> int:
# Если уже были chunk-файлы, значит итог должен быть в формате sitemapindex.
if self.chunk_files:
self._flush_chunk()
self._write_sitemap_index(generated_at)
return len(self.chunk_files)
# Иначе пишем единый sitemap.xml с URLSet.
self._write_single_sitemap()
return 1
def _flush_chunk(self) -> None:
if not self.current_urls:
return
chunk_idx = len(self.chunk_files)
if chunk_idx >= self.max_files_qty:
raise RuntimeError(
"Превышено максимальное количество sitemap-файлов. "
f"Текущий лимит: {self.max_files_qty}."
)
file_name = f"sitemap{chunk_idx:04d}.xml"
self._write_urlset(self.output_dir / file_name, self.current_urls)
self.chunk_files.append(file_name)
# Сбрасываем буфер для следующего chunk-файла.
self.current_urls = []
self.current_size = 128
def _write_single_sitemap(self) -> None:
self._write_urlset(self.output_dir / "sitemap.xml", self.current_urls)
self.current_urls = []
self.current_size = 128
def _write_sitemap_index(self, generated_at: datetime) -> None:
root = ET.Element("sitemapindex", xmlns=SITEMAP_XMLNS)
for file_name in self.chunk_files:
sitemap_element = ET.SubElement(root, "sitemap")
ET.SubElement(sitemap_element, "loc").text = f"{self.public_base_url}/{file_name}"
ET.SubElement(sitemap_element, "lastmod").text = _as_sitemap_date(generated_at)
xml_bytes = ET.tostring(root, encoding="utf-8", xml_declaration=True)
(self.output_dir / "sitemap.xml").write_bytes(xml_bytes)
@staticmethod
def _write_urlset(file_path: Path, urls: Iterable[ET.Element]) -> None:
root = ET.Element("urlset", xmlns=SITEMAP_XMLNS)
for url in urls:
root.append(url)
xml_bytes = ET.tostring(root, encoding="utf-8", xml_declaration=True)
file_path.write_bytes(xml_bytes)
@staticmethod
def _build_url_element(loc: str, lastmod: datetime, changefreq: str, priority: float) -> ET.Element:
element = ET.Element("url")
ET.SubElement(element, "loc").text = loc
ET.SubElement(element, "lastmod").text = _as_sitemap_date(lastmod)
ET.SubElement(element, "changefreq").text = changefreq
ET.SubElement(element, "priority").text = f"{priority:.2f}"
return element
def build_sitemaps(
output_dir: Path,
site_base_url: str,
sitemap_url_prefix: str,
max_items: int,
max_file_size: int,
max_files_qty: int,
compare_min_depth: int = 2,
compare_max_depth: int = 4,
) -> SitemapBuildResult:
"""Оркестратор полного прогона сборки sitemap-файлов."""
time_start = timezone.now()
generated_at = timezone.now()
compare_lastmod = generated_at.date().replace(day=1)
latest_blog_modify = BlogPosts.objects.filter(
dPostDataBegin__lte=timezone.now(),
bPublished=True,
bArchive=False,
).aggregate(lastmod=Max("dPostDataModify"))["lastmod"]
latest_profile_modify = PVCprofiles.objects.aggregate(lastmod=Max("dProfileModify"))["lastmod"]
latest_seria_modify = Seria_Info.objects.aggregate(lastmod=Max("dSeriaInfoModify"))["lastmod"]
latest_company_modify = MerchantBrand.objects.annotate(
last_offer_modify=Max("merchantoffice__ouruser__setkit__priceoffer__dOfferModify"),
last_office_modify=Max("merchantoffice__dOfficeDataModify"),
).aggregate(lastmod=Max("last_offer_modify"), lastmod_office=Max("last_office_modify"))
latest_company_date = latest_company_modify.get("lastmod") or latest_company_modify.get("lastmod_office")
base_url = site_base_url.rstrip("/")
url_prefix = sitemap_url_prefix.strip("/")
public_sitemap_base = f"{base_url}/{url_prefix}" if url_prefix else base_url
writer = SitemapXmlWriter(
output_dir=output_dir,
public_base_url=public_sitemap_base,
max_items=max_items,
max_file_size=max_file_size,
max_files_qty=max_files_qty,
)
writer.cleanup_old()
# Источники URL. Порядок можно менять, если нужно управлять наполнением chunk-файлов.
sitemaps = [
StaticPagesSitemap(
items=[
{"loc": "/", "lastmod": generated_at, "changefreq": "weekly", "priority": 1.00},
{"loc": "/catalog", "lastmod": generated_at, "changefreq": "weekly", "priority": 0.88},
{"loc": "/catalog/profile", "lastmod": latest_profile_modify, "changefreq": "weekly", "priority": 0.92},
{"loc": "/catalog/seria", "lastmod": latest_seria_modify, "changefreq": "weekly", "priority": 0.95},
{"loc": "/catalog/standard_opening", "lastmod": latest_seria_modify, "changefreq": "monthly", "priority": 0.86},
{"loc": "/catalog/company", "lastmod": latest_company_date, "changefreq": "weekly", "priority": 0.90},
{"loc": "/stat/rating/profiles_rank", "lastmod": latest_profile_modify, "changefreq": "monthly", "priority": 0.76},
]
),
BlogListSitemap(lastmod_value=latest_blog_modify),
BlogPostSitemap(),
ProfileManufactureSitemap(),
ProfileModelSitemap(),
SeriaDetailSitemap(),
CompanyDetailSitemap(),
SingleWindowSitemap(lastmod_value=generated_at),
BuildingOffersSitemap(lastmod_value=generated_at),
CompareOffersSitemap(
lastmod_value=compare_lastmod,
min_depth=compare_min_depth,
max_depth=compare_max_depth,
),
]
for sitemap in sitemaps:
for item in sitemap.items():
location = sitemap.location(item)
lastmod = sitemap.lastmod(item)
if not location.startswith("/"):
location = f"/{location}"
sitemap_changefreq = sitemap.changefreq(item) if callable(getattr(sitemap, "changefreq", None)) else str(sitemap.changefreq)
sitemap_priority = sitemap.priority(item) if callable(getattr(sitemap, "priority", None)) else float(sitemap.priority)
writer.add_url(
loc=f"{base_url}{location}",
lastmod=lastmod,
changefreq=sitemap_changefreq,
priority=sitemap_priority,
)
files_count = writer.finalize(generated_at=generated_at)
elapsed = (timezone.now() - time_start).total_seconds()
return SitemapBuildResult(
total_urls=writer.total_urls,
files_count=files_count,
elapsed_seconds=elapsed,
output_dir=output_dir,
)
class Command(BaseCommand):
help = "Генерирует sitemap.xml и sitemapNNNN.xml в файловый кэш."
def add_arguments(self, parser):
parser.add_argument(
"--compare-min-depth",
type=int,
default=2,
help="Минимальная глубина комбинаций compare_offers (по умолчанию 2).",
)
parser.add_argument(
"--compare-max-depth",
type=int,
default=4,
help="Максимальная глубина комбинаций compare_offers (по умолчанию 4).",
)
parser.add_argument(
"--max-items",
type=int,
default=40000,
help="Максимум URL в одном sitemap-файле (по умолчанию 40000).",
)
parser.add_argument(
"--max-file-size",
type=int,
default=5242880,
help="Максимальный размер sitemap-файла в байтах (по умолчанию 5242880).",
)
parser.add_argument(
"--max-files-qty",
type=int,
default=998,
help="Максимум вложенных sitemap-файлов (по умолчанию 998).",
)
def handle(self, *args, **options):
# Валидация глубины compare перед запуском тяжелой части генерации.
compare_min_depth = options["compare_min_depth"]
compare_max_depth = options["compare_max_depth"]
if compare_min_depth > compare_max_depth:
raise CommandError("--compare-min-depth не может быть больше --compare-max-depth")
result = build_sitemaps(
output_dir=Path(settings.SITEMAP_ROOT),
site_base_url=settings.SITE_BASE_URL,
sitemap_url_prefix=settings.SITEMAP_URL_PREFIX,
max_items=options["max_items"],
max_file_size=options["max_file_size"],
max_files_qty=options["max_files_qty"],
compare_min_depth=compare_min_depth,
compare_max_depth=compare_max_depth,
)
# Человекочитаемый отчет для логов CI/CD и контейнерных entrypoint-скриптов.
if result.files_count == 1:
self.stdout.write(
self.style.SUCCESS(
f"Создан единственный sitemap.xml. URL-ов: {result.total_urls}. "
f"Время: {result.elapsed_seconds:.2f} сек."
)
)
else:
self.stdout.write(
self.style.SUCCESS(
f"Создан каскад sitemap. Файлов: {result.files_count}. URL-ов: {result.total_urls}. "
f"Время: {result.elapsed_seconds:.2f} сек."
)
)
+15 -12
View File
@@ -325,7 +325,7 @@ def report_one_win_price(request: HttpRequest, win_width_mm: str = '670', win_he
:param win_id: str -- ID проема (см. таблицу oknardia_win_mountdim)
:return response: HttpResponse -- исходящий http-ответ
"""
time_start = time.time()
time_start = time.perf_counter()
to_template = {}
try:
# т.к. для вызова GetFlapDim4BigPictures нужно иметь внутри queryset поле iQuantity нельзя использовать
@@ -439,7 +439,7 @@ def report_one_win_price(request: HttpRequest, win_width_mm: str = '670', win_he
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.time() - time_start)
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "price/price_offers_for_one_window.html", to_template)
@@ -452,11 +452,11 @@ def next_one_win_price(request: HttpRequest, win_id='16', frame_begin_n="0"):
:param frame_begin_n: str -- Номер записи с которой начинается фрейм с ценами
:return: HttpResponse --
"""
time_start = time.time()
time_start = time.perf_counter()
to_template = report_price_frame(0, 1, 0, 0, int(frame_begin_n), 0, int(win_id))
to_template.update({'MOUNT_DIM_PER_OFFER': 1,
'WIN_ID': int(win_id),
'ticks': float(time.time() - time_start)})
'ticks': float(time.perf_counter() - time_start)})
return render(request, "price/price_offers_for_one_window_frame.html", to_template)
@@ -470,7 +470,7 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
:param slug: str - slug адреса здания
:return: response: HttpResponse
"""
time_start = time.time()
time_start = time.perf_counter()
msg = ""
to_template = {}
try:
@@ -644,7 +644,10 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
# получаем последние визиты всех посетителей из базы
log_visit = get_last_all_user_visit_list()
id_last_visit_log = log_visit[0]['id'] + 1
if log_visit[0]['id'] is not None:
id_last_visit_log = log_visit[0]['id'] + 1
else:
id_last_visit_log = 1
# print("id_last_visit_log:", id_last_visit_log)
to_template.update({'LOG_VISIT': log_visit})
if id_last_visit_log > MAX_LEN_RING_LOG_BUFFER: # максимальный размер циклического буфера
@@ -654,14 +657,14 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
log_entry.sLogAddress = to_template["ADDRESS"]
log_entry.sLogNameApartment = to_template["APART"]
log_entry.sLogURL = f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}"
log_entry.dLogVisitTime = time.time()
log_entry.dLogVisitTime = time.perf_counter()
log_entry.save() # UPDATE
except ObjectDoesNotExist:
log_entry = LogVisitPriceReport(
sLogAddress=to_template["ADDRESS"],
sLogNameApartment=to_template["APART"],
sLogURL=f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}",
dLogVisitTime=time.time()
dLogVisitTime=time.perf_counter()
)
log_entry.save() # INSERT
@@ -673,11 +676,11 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
"LastURL": f"/{build_id}/{apart_id}/{to_template['ADDRESS_T']}",
"LastAddress": to_template["ADDRESS"],
"LastApart": to_template["APART"],
"Time": time.time()}
"Time": time.perf_counter()}
last_visit.insert(0, Item) # Добавляем текущий Item в начало
last_visit = json.dumps(last_visit[:3]) # упаковываем json без пробелов (три записи)
# print u"сейчас запишем вот эту куку:", LastVisit
to_template.update({'ticks': float(time.time() - time_start)})
to_template.update({'ticks': float(time.perf_counter() - time_start)})
response = render(request, "price/price_list.html", to_template)
response.set_cookie("LastVisit", last_visit, max_age=7862400) # ставим или перезаписываем куки (91 день)
return response
@@ -699,7 +702,7 @@ def next_price_frame(request: HttpRequest, apart_id: str = "1", mount_dim_per_o
:param frame_begin_n: str -- Номер записи с которой начинается фрейм с ценами
:return: HttpResponse -- HTTP-ответ
"""
time_start = time.time()
time_start = time.perf_counter()
# получаем данные для фрейма ценовых предложений
price_frame = report_price_frame(int(apart_id), int(mount_dim_per_offer), float(address_longitude),
float(address_latitude), int(frame_begin_n))
@@ -708,5 +711,5 @@ def next_price_frame(request: HttpRequest, apart_id: str = "1", mount_dim_per_o
'MOUNT_DIM_PER_OFFER': mount_dim_per_offer,
'ADDRESS_LAT': address_latitude,
'ADDRESS_LON': address_longitude,
'ticks': float(time.time() - time_start)})
'ticks': float(time.perf_counter() - time_start)})
return render(request, "price/price_list_frame.html", to_template)
+4 -4
View File
@@ -80,7 +80,7 @@ def compare_offers(request: HttpRequest, to_compare: str = "1,2") -> HttpRespons
:param to_compare: str -- список ,через запятую, id оконных наборов (Set) для сравнения
:return: HttpResponse --
"""
time_start = time.time()
time_start = time.perf_counter()
to_template = {}
try:
# Этот блок нужен для 302-переадресации, когда разные URL отдают одинаковые страницы.
@@ -539,7 +539,7 @@ def compare_offers(request: HttpRequest, to_compare: str = "1,2") -> HttpRespons
# получаем последние визиты всех посетителей из базы
# id2log, log_visit = get_last_all_user_visit_list()
'LOG_VISIT': get_last_all_user_visit_list(),
'ticks': float(time.time() - time_start)
'ticks': float(time.perf_counter() - time_start)
})
return render(request, "report/report_compare_set.html", to_template)
@@ -551,7 +551,7 @@ def show_rating_components(request: HttpRequest, win_set: str = "1") -> HttpResp
:param win_set: str -- id оконного набора, для которого показать состав рейтинга
:return: HttpResponse --
"""
time_start = time.time()
time_start = time.perf_counter()
to_template = {}
try:
win_set = int(win_set)
@@ -596,5 +596,5 @@ def show_rating_components(request: HttpRequest, win_set: str = "1") -> HttpResp
"коммерческое предложение, коммерческих предложения,"
" коммерческих предложений"),
'TEST': win_set,
'ticks': float(time.time() - time_start)})
'ticks': float(time.perf_counter() - time_start)})
return render(request, "report/show_rating_components.html", to_template)
+325 -181
View File
@@ -7,8 +7,6 @@ import django.utils.dateformat
import django.utils.timezone
from oknardia.settings import *
import time
import random
import pytils
# Главная страница для вызова служебных процедур.
@@ -18,18 +16,18 @@ def service(request: HttpRequest) -> HttpResponse:
:param request: HttpRequest
:return: HttpResponse
"""
time_start = time.time()
time_start = time.perf_counter()
# проверка на аутентификацию
print(request.user.is_authenticated)
# print(request.user.is_authenticated)
if not request.user.is_authenticated:
return redirect("/service/not-denice")
return render(request, "service/index.html", {'ticks': float(time.time()-time_start)})
return render(request, "service/index.html", {'ticks': float(time.perf_counter()-time_start)})
# страничка, на которую переадресует служебный интерфейс, если нет аутентификации.
def not_denice(request):
time_start = time.time()
return render(request, "service/not_denice.html", {'ticks': float(time.time()-time_start)})
time_start = time.perf_counter()
return render(request, "service/not_denice.html", {'ticks': float(time.perf_counter()-time_start)})
def tmp(request: HttpRequest) -> HttpResponse:
@@ -38,187 +36,333 @@ def tmp(request: HttpRequest) -> HttpResponse:
:param request:
:return:
"""
t_start = time.time()
return render(request, "service/tmp.html", {'TAU': float(time.time()-t_start)})
t_start = time.perf_counter()
return render(request, "service/tmp.html", {'TAU': float(time.perf_counter()-t_start)})
SITEMAP_MAX_ITEM = 40000 # максимальное число URL-ов в sitemap.xml -- 50000
SITEMAP_MAX_FILE_SIZE = 5242880 # максимальный размер файла sitemap.xml -- 10Mb (10485760 байт)
SITEMAP_MAX_FILES_QTY = 998 # максимальный число вложенных sitemap.xml -- 1000
def str_time() -> str:
""" Возвращает текущее время в ISO 8601 со смещением от текущего часового пояса
def make_rating(request: HttpRequest) -> HttpResponse:
"""
return django.utils.dateformat.format(django.utils.timezone.now(), 'c')
Вычисляем (каждый раз заново) рейтинги оконных профилей, стеклопакетов и оконных наборов.
Вычисление базируется на ренкинге. В базовом ренкинге участвуют только стеклопакеты и профиля
присутствующие в коммерческих предложениях размещенных в ОКНАРДИИ.
Ренкинг профилей: Для получения ранка вся совокупность профилей из коммерческих предложений сортируется
по тому или иному признаку (характеристике). Каждому профилю присваивается ранк, который вычисляется как
весу той или иной характеристики и порядковому номеру профиля в сортированному по этому признаку
(характеристике) в списке.
def make_site_maps (request: HttpRequest) -> HttpResponse:
"""Функция создания sitemap.xml ... периодически надо вызывать через crone
ВНИМАНИЕ ТЕХНИЧЕСКИЙ ДОЛГ:
Система ренкинга разрабатывалась когда в базе было уже достаточно предложений. Возможно, если
объектов ренкинга будет мало что-то не сработает. И выдаст ошибку.
:param request: request
:return: HttpResponse ( msg )
:param request: HttpRequest -- запрос
:return: HttpResponse -- ответ
"""
time_start = time.perf_counter()
msg = ""
time_start = time.time()
count_total_item = 0
count_item_per_file = 0
count_file = 0
# форматирование даты-времени в ISO 8601 со смещением от текущего часового пояса
# str_time = django.utils.dateformat.format(django.utils.timezone.now(), 'c') # форматирование даты в ISO 8601
# ПОЛУЧАЕМ ВСЕ СТРАНИЧКИ С ЦЕНАМИ ДЛЯ ОДИНОЧНОГО ПРОЕМА
q1 = Win_MountDim.objects.raw("SELECT"
" oknardia_win_mountdim.iWinWidth,"
" oknardia_win_mountdim.iWinHight,"
" oknardia_win_mountdim.id,"
" COUNT(oknardia_priceoffer.kOffer2MountDim_id) AS NumOffer,"
" oknardia_win_mountdim.sFlapConfig "
"FROM oknardia_priceoffer"
" INNER JOIN oknardia_win_mountdim"
" ON oknardia_priceoffer.kOffer2MountDim_id = oknardia_win_mountdim.id "
"GROUP BY oknardia_win_mountdim.id,"
" oknardia_win_mountdim.iWinWidth,"
" oknardia_win_mountdim.iWinHight,"
" oknardia_win_mountdim.sFlapConfig "
"ORDER BY COUNT(oknardia_priceoffer.kOffer2MountDim_id);")
for i in q1:
msg += f" <url>\n" \
f" <loc>https://oknardia.ru/tsena-odnogo-okna/{int(i.iWinWidth*10)}x{int(i.iWinHight*10)}mm/tip{i.id}</loc>\n"\
f" <lastmod>{str_time()}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.5</priority>\n" \
f" </url>\n"
count_total_item += 1
# print "~~~> ", countTotalItem, " ::: /compare_offers/", Count
count_item_per_file += 1
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
msg = f"<?xml version='1.0' encoding='UTF-8'?>" \
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
f.write(msg)
count_item_per_file = 0
count_file += 1 # счетчик файлов
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
break
msg = "" # обнулить буфер для записи файла
# ВСЕ СТРАНИЧКИ С ЦЕНОВЫМИ ПРЕДЛОЖЕНИЯМИ ПО АДРЕСАМ
q1 = Building_Info.objects.raw(
"SELECT DISTINCT oknardia_building_info.sAddress, oknardia_building_info.id as id,"
" oknardia_apartment_type.id AS ap_id "
"FROM oknardia_building_info"
" INNER JOIN oknardia_seria_info"
" ON oknardia_building_info.kSeria_Link_id = oknardia_seria_info.id"
" INNER JOIN oknardia_apartment_type"
" ON oknardia_apartment_type.kSeria_id = oknardia_seria_info.kRoot_id "
"ORDER BY oknardia_building_info.id;")
list_build = list(q1)
random.shuffle(list_build) # перемешиваем случайным образом, чтобы поисковики видели изменения sitemap
for i in list_build:
msg += f" <url>\n <loc>https://oknardia.ru/{i.id}/{i.ap_id}/{pytils.translit.slugify(i.sAddress)}</loc>\n" \
f" <lastmod>{str_time()}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.5</priority>\n" \
f" </url>\n"
count_total_item += 1
# print("===> ", count_total_item, " ::: ", i.id, '/', i.ap_id, '/', pytils.translit.slugify(i.sAddress), sep="")
count_item_per_file += 1
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
msg = f"<?xml version='1.0' encoding='UTF-8'?>\n" \
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
f.write(msg)
count_item_per_file = 0
count_file += 1 # счетчик файлов
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
break
msg = "" # обнулить буфер для записи файла
# ДОБАВЛЯЕМ В SITEMAP ВСЕ СТРАНИЧКИ СО СРВНЕНИЕМ НАБОРОВ
dim_comp = compare()
random.shuffle(dim_comp)
for i in dim_comp:
msg += f" <url>\n <loc>https://oknardia.ru/compare_offers/{i}</loc>\n <lastmod>{str_time()}</lastmod>\n" \
f" <changefreq>weekly</changefreq>\n <priority>0.45</priority>\n </url>\n"
count_total_item += 1
count_item_per_file += 1
if (count_item_per_file > SITEMAP_MAX_ITEM) or (len(msg) > SITEMAP_MAX_FILE_SIZE):
# Файл sitemap.xml заполнен... нужно записать и продолжить записывать в следующем
msg = f"<?xml version='1.0' encoding='UTF-8'?>\n" \
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>"
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
f.write(msg)
count_item_per_file = 0
count_file += 1 # счетчик файлов
msg = "" # обнулить буфер для записи файла
if count_file > SITEMAP_MAX_FILES_QTY: # максимально число файлов SITEMAP_MAX_FILES_QTY
break
# ЗАВЕРШАЕМ
if count_file == 0:
# Все ссылки уместились в один sitemap.xml... просто его записать
with open(f"{SITEMAP_ROOT}sitemap.xml", "w", encoding="utf-8") as f:
f.write(f"<?xml version='1.0' encoding='UTF-8'?>\n"
f"<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>")
print(SITEMAP_ROOT)
msg = f"Создан единственный sitemap.xml\nВсего ссылок: {count_total_item:06d}"
else:
# Файлов sitemap.xml много.
# Создаем завершающий файл sitemap
with open(f"{SITEMAP_ROOT}sitemap{count_file:04d}.xml", "w", encoding="utf-8") as f:
f.write(f"<?xml version='1.0' encoding='UTF-8'?>\n<urlset "
f"xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n{msg}</urlset>")
# Создаём объединяющий sitemap.xml с перечислением всего множества sitemap-файлов...
msg = "<?xml version='1.0' encoding='UTF-8'?>\n" \
"<sitemapindex xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n"
for i in range(0, count_file+1):
msg += f" <sitemap>\n <loc>https://oknardia.ru/sitemap{i:04d}.xml</loc>\n" \
f" <lastmod>{str_time()}</lastmod>\n </sitemap>\n"
msg += u"</sitemapindex>"
with open(f"{SITEMAP_ROOT}sitemap.xml", "w", encoding="utf-8") as f:
f.write(msg)
msg = f"Создан каскадный sitemap.xml\nВсего вложенных файлов: {count_file+1:04d}\n" \
f"Всего ссылок: {count_total_item:08d}"
print(msg)
return HttpResponse(f"<pre>{msg}\n\nвремя выполнения: {float(time.time()-time_start)} сек.</pre>")
def compare() -> list:
""" Возвращает список сравнения из всех возможных вариантов сравнения оконных наборов (из доступных в базе)
:return: список сравнения
"""
q_set_kit = SetKit.objects.raw('SELECT oknardia_setkit.id, oknardia_setkit.sSetActive '
'FROM oknardia_setkit '
'WHERE oknardia_setkit.sSetActive = TRUE')
count = 0
dim_comp = []
l_set_kit = list(q_set_kit)
for i1 in l_set_kit:
for i2 in l_set_kit:
if i1.id >= i2.id:
continue
dim_comp.append(f"{i1.id},{i2.id}")
count += 1
for i3 in l_set_kit:
if i2.id >= i3.id:
# ВЫЧИСЛЯЕМ РЕЙТИНГ ПРОФИЛЕЙ
# устанавливаем рейтинг всех профилей в базе в ноль
profile_all_num = PVCprofiles.objects.all().update(fProfileRating=0.0)
to_template = {'NUM_PROFILE_TOTAL': profile_all_num} # засовываем данные в шаблон
q = PVCprofiles.objects.raw("SELECT"
" oknardia_pvcprofiles.*,"
" COUNT(oknardia_priceoffer.id) AS NumOffer "
"FROM oknardia_setkit"
" INNER JOIN oknardia_priceoffer"
" ON oknardia_setkit.id = oknardia_priceoffer.kOffer2SetKit_id"
" RIGHT OUTER JOIN oknardia_pvcprofiles"
" ON oknardia_setkit.kSet2PVCprofiles_id = oknardia_pvcprofiles.id "
"GROUP BY oknardia_pvcprofiles.id;")
profile_use_list = list(q)
# получаем словарь из RawQuerySet
PVC_Dictionary = Prepare_PVC_Dictionary(profile_use_list)
# получаем рейтинги
dim, PVC_Dictionary = RankingPVC(PVC_Dictionary)
to_template.update(dim) # засовываем данные в шаблон
# сортируем по полученному рейтингу
PVC_Dictionary = sorted(PVC_Dictionary, key=lambda item: item["TmpRating"])
# print u"РЕЙТИНГИ ПРОФИЛЕЙ IN USE"
# найдем минимальный и максимальный ранкинг для последующей нормализации
NumMaxRank = 0
NumMinRank = -1
j = 0
for i in PVC_Dictionary:
if i["NumOffer"] != 0:
NumMaxRank = j
if NumMinRank == -1:
NumMinRank = j
j += 1
j = 0
for i in PVC_Dictionary:
obj = PVCprofiles.objects.get(id=i["id"])
try:
GettedJSON = json.loads(obj.sProfileDescription)
except:
GettedJSON = {}
if i["NumOffer"] != 0:
try: del GettedJSON[KEY_RATING_VIRTUAL]
except: pass
GettedJSON[KEY_RATING] = i["RatingConsist"]
# GettedJSON.update({KEY_RATING:i["RatingConsist"]})
else:
try: del GettedJSON[KEY_RATING]
except: pass
GettedJSON[KEY_RATING_VIRTUAL] = i["RatingConsist"]
# GettedJSON.update({KEY_RATING_VIRTUAL:i["RatingConsist"]})
obj.sProfileDescription = json.dumps(GettedJSON,
separators=(",",":"),
sort_keys=True,
encoding="utf-8",
ensure_ascii=False)
if j <= NumMaxRank:
obj.fProfileRating = Normalize(i["TmpRating"],PVC_Dictionary[NumMaxRank]["TmpRating"]) * (RARING_PVC_PROFILE_MAX-RARING_PVC_PROFILE_MIN) + RARING_PVC_PROFILE_MIN
else:
obj.fProfileRating = 5.0
# print "id_PVC:", i["id"], u"\tΣ:", obj.fProfileRating, u"\tСостав:",
# print json.dumps(i["RatingConsist"], separators=(",",":"), encoding="utf-8", ensure_ascii=False)
obj.save()
j += 1
# вычисляем рейтинги стеклопакетоа
# ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
# устанавливаем рейтинг всех стеклопакетоа в базе в ноль
GlazingAllNum = Glazing.objects.all().update(fGlazingRating=0.0)
to_template.update({'NUM_GLAZING_TOTAL':GlazingAllNum}) # засовываем данные в шаблон
q = Glazing.objects.raw("SELECT"
" oknardia_glazing.*,"
" COUNT(oknardia_priceoffer.id) AS NumOffer "
"FROM oknardia_setkit"
" INNER JOIN oknardia_priceoffer"
" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
" INNER JOIN oknardia_glazing"
" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id "
"GROUP BY oknardia_glazing.id;")
GlazingUseList = list(q)
# получаем словарь из RawQuerySet
GLAZ_Dictionary = Prepare_GLAZ_Dictionary(GlazingUseList)
# получаем рейтинги
dim, GLAZ_Dictionary = RankingGlazing(GLAZ_Dictionary)
to_template.update(dim) # засовываем данные в шаблон
# сортируем по полученному рейтингу
GLAZ_Dictionary = sorted(GLAZ_Dictionary, key=lambda item: item["TmpRating"])
# print u"РЕЙТИНГИ СТЕКЛОПАКЕТОВ IN USE"
for i in GLAZ_Dictionary:
obj = Glazing.objects.get(id=i["id"])
obj.fGlazingRating = Normalize(i["TmpRating"], ValMax=GLAZ_Dictionary[-1]["TmpRating"]) * (RARING_GLAZING_MAX-RARING_GLAZING_MIN) + RARING_GLAZING_MIN
try:
GettedJSON = json.loads(obj.sGlazingDescription)
except:
GettedJSON = {}
try: del GettedJSON[KEY_RATING_VIRTUAL]
except: pass
GettedJSON.update({KEY_RATING:i["RatingConsist"]})
obj.sGlazingDescription = json.dumps(GettedJSON,
separators=(",",":"),
sort_keys=True,
encoding="utf-8",
ensure_ascii=False)
# print u"id:",i["id"], u"\tRank:", i["TmpRating"], u"\rate:", obj.fGlazingRating, u"\tGLAZ:", i["sGlazingMark"]
obj.save()
# получаем все стеклопакеты, чтобы забацать рейтинг и для тех, которые есть в каталоге но нет в КП
q = Glazing.objects.raw("SELECT oknardia_glazing.* "
"FROM oknardia_glazing;")
GlazingAllList = list(q)
# получаем словарь из RawQuerySet
GLAZ_Dictionary = Prepare_GLAZ_Dictionary(GlazingAllList)
# получаем рейтинги
dim, GLAZ_Dictionary = RankingGlazing(GLAZ_Dictionary)
GLAZ_Dictionary = sorted(GLAZ_Dictionary, key=lambda item: item["TmpRating"])
if GlazingAllNum > len(GlazingUseList):
CutStartIndex = -1
CutStartRatingValue = 0.
CutEndIndex = -1
CutEndRatingValue = 0.
for i in range(0, GlazingAllNum):
# print i, GLAZ_Dictionary[i]["id"], u"\trank --> ", GLAZ_Dictionary[i]["TmpRating"], "\t(",
# print GLAZ_Dictionary[i]["fGlazingRating"], ")\tFormulaGLAZING:", GLAZ_Dictionary[i]["sGlazingMark"]
if GLAZ_Dictionary[i]["fGlazingRating"] != 0.:
# нашли конец следующего отрезка, нужно отрезок переопределить
CutStartRatingValue = CutEndRatingValue
CutStartIndex = CutEndIndex
CutEndRatingValue = GLAZ_Dictionary[i]["fGlazingRating"]
CutEndIndex = i
if CutEndIndex == 0:
continue
dim_comp.append(f"{i1.id},{i2.id},{i3.id}")
count += 1
for i4 in l_set_kit:
if i3.id >= i4.id:
continue
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id}")
count += 1
for i5 in l_set_kit:
if i4.id >= i5.id:
continue
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id},{i5.id}")
count += 1
for i6 in l_set_kit:
if i5.id >= i6.id:
continue
dim_comp.append(f"{i1.id},{i2.id},{i3.id},{i4.id},{i5.id},{i6.id}")
count += 1
# random.shuffle(dim_comp)
# for i1 in dim_comp:
# print(i1)
# print(f"---------------{count}---------------")
return dim_comp
else:
# надо перебрать все объекты внутри отрезка
for j in range(CutStartIndex+1, CutEndIndex):
# и пересчитать рейтинги внутри этого, нового отрезка
GLAZ_Dictionary[j]["fGlazingRating"] = CutStartRatingValue + (GLAZ_Dictionary[j]["TmpRating"]-GLAZ_Dictionary[CutStartIndex]["TmpRating"])*((CutEndRatingValue-CutStartRatingValue)/(GLAZ_Dictionary[CutEndIndex]["TmpRating"]-GLAZ_Dictionary[CutStartIndex]["TmpRating"]))
# print j, GLAZ_Dictionary[j]["id"], u"\trank >>> ", GLAZ_Dictionary[j]["TmpRating"], "\t(",
# print GLAZ_Dictionary[j]["fGlazingRating"], ")\tFormulaGLAZING:", GLAZ_Dictionary[j]["sGlazingMark"]
# и записать этот рейтинг в базу
obj = Glazing.objects.get(id=GLAZ_Dictionary[j]["id"])
obj.fGlazingRating = GLAZ_Dictionary[j]["fGlazingRating"]
try:
GettedJSON = json.loads(obj.sGlazingDescription)
except:
GettedJSON = {}
try: del GettedJSON[KEY_RATING]
except: pass
GettedJSON.update({KEY_RATING_VIRTUAL:GLAZ_Dictionary[j]["RatingConsist"]})
obj.sGlazingDescription = json.dumps(GettedJSON,
separators=(",",":"),
sort_keys=True,
encoding="utf-8",
ensure_ascii=False)
obj.save()
for j in range(CutEndIndex+1, GlazingAllNum):
# пересчитать рейтинги хвоста (для отрезка после последнего отрейтингованного)
# внимание это код не для работы со словарями. при ревизии переделать GlazingAllList[j].fGlazingRating = CutStartRatingValue + (GlazingAllList[j].TmpRating-GlazingAllList[CutStartIndex].TmpRating)*((CutEndRatingValue-CutStartRatingValue)/(GlazingAllList[CutEndIndex].TmpRating-GlazingAllList[CutStartIndex].TmpRating))
GLAZ_Dictionary[j]["fGlazingRating"] = RARING_GLAZING_MAX # т.к. для виртуальный рейтинг иногда снижается, то ставим 5*
# и записать этот рейтинг в базу
obj = Glazing.objects.get(id=GLAZ_Dictionary[j]["id"])
obj.fGlazingRating = GLAZ_Dictionary[j]["fGlazingRating"]
try:
GettedJSON = json.loads(obj.sGlazingDescription)
except:
GettedJSON = {}
try: del GettedJSON[KEY_RATING]
except: pass
GettedJSON.update({KEY_RATING_VIRTUAL:GLAZ_Dictionary[j]["RatingConsist"]})
obj.sGlazingDescription = json.dumps(GettedJSON,
separators=(",",":"),
sort_keys=True,
encoding="utf-8",
ensure_ascii=False)
obj.save()
# вычисляем рейтинги наборов (стеклопакет + профиль + сопутсвующие услуги т.п.
# ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
# устанавливаем рейтинг всех наборов в базе в ноль
SetAllNum = SetKit.objects.all().update(fSetRating=0.0)
to_template.update({'NUM_SET_TOTAL':SetAllNum}) # засовываем данные в шаблон
q = SetKit.objects.raw("SELECT"
" COUNT(oknardia_priceoffer.id) AS NumOffer,"
" MAX(oknardia_priceoffer.dOfferModify) AS dModify,"
" oknardia_pvcprofiles.fProfileRating,"
" oknardia_glazing.fGlazingRating,"
" oknardia_setkit.*,"
" oknardia_merchantoffice.sOfficeDiscountMetaFormula "
"FROM oknardia_setkit"
" INNER JOIN oknardia_priceoffer"
" ON oknardia_priceoffer.kOffer2SetKit_id = oknardia_setkit.id"
" INNER JOIN oknardia_glazing"
" ON oknardia_setkit.kSet2Glazing_id = oknardia_glazing.id"
" INNER JOIN oknardia_pvcprofiles"
" ON oknardia_pvcprofiles.id = oknardia_setkit.kSet2PVCprofiles_id "
" INNER JOIN oknardia_ouruser"
" ON oknardia_setkit.kSet2User_id = oknardia_ouruser.id"
" INNER JOIN oknardia_merchantoffice"
" ON oknardia_ouruser.kMerchantOffice_id = oknardia_merchantoffice.id "
"WHERE oknardia_setkit.sSetActive = TRUE "
"GROUP BY oknardia_pvcprofiles.fProfileRating,"
" oknardia_glazing.fGlazingRating,"
" oknardia_merchantoffice.sOfficeDiscountMetaFormula,"
" oknardia_setkit.sSetActive, oknardia_setkit.id "
"ORDER BY MAX(oknardia_priceoffer.dOfferModify);")
# q = SetKit.objects.order_by("dModify")
SetUseList = list(q)
to_template.update({'NUM_SET': len(SetUseList) })
SetDictionary = []
# Превратим RawQuerySet в массив словарей (почти JSON). Так получится избежать "макаронного кода".
# Заодно переопределяем для правильного ранжирования некоторые параметры из строк в цифры.
for i in range(0,len(SetUseList)):
SetDictionary.append(q[i].__dict__)
if SetDictionary[i]["sSetSill"].lower() in [u"нет",u"-",u"",""," "]:
SetDictionary[i]["sSetSill"] = 0 # Подоконника нет
else: SetDictionary[i]["sSetSill"] = 1 # Подоконник есть
if SetDictionary[i]["sSetPanes"].lower() in [u"нет",u"-",u"",""," "]:
SetDictionary[i]["sSetPanes"] = 0 # Водоотлив нет
else: SetDictionary[i]["sSetPanes"] = 1 # Водоотлив есть
if SetDictionary[i]["sSetSlope"].lower() in [u"нет",u"-",u"",""," "]:
SetDictionary[i]["sSetSlope"] = 0 # Откос нет
else: SetDictionary[i]["sSetSlope"] = 1 # Откос есть
if SetDictionary[i]["sSetClimateControl"].lower() in [u"нет",u"-",u"",""," "]:
SetDictionary[i]["sSetClimateControl"] = 0 # Климат-контроль нет
else: SetDictionary[i]["sSetClimateControl"] = 1 # Климат-контроль есть
try:
# print eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].keys()
# print max(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].values())
SetDictionary[i].update({"DiscountMax": max(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].values())})
SetDictionary[i]["sOfficeDiscountMetaFormula"] = len(eval(SetDictionary[i]["sOfficeDiscountMetaFormula"])[KEY_DICSOUNT].keys())
except:
SetDictionary[i].update({"DiscountMax": 0})
SetDictionary[i]["sOfficeDiscountMetaFormula"] = 0
# Отранжируем наборы по параметру "дата последнего обновления цены" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "dModify", key_weight=RANK_STEP_SET_MODIFY,
rank_name=u"Актуальность", revers=False)
to_template.update({'S_Modify_Step': RANK_STEP_SET_MODIFY })
to_template.update({'S_Modify_MaxRank': MaxRank })
# Отранжируем наборы по параметру "доставка включена в стоимость" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "bSetDelivery", key_weight=RANK_STEP_SET_DELIVERY,
rank_name=u"Доставка", revers=False)
to_template.update({'S_Delivery_Step': RANK_STEP_SET_DELIVERY })
to_template.update({'S_Delivery_MaxRank': MaxRank })
# Отранжируем наборы по параметру Демонтаж/Монтаж" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "bSetUninstallInstall", key_weight=RANK_STEP_SET_UNINSTALL_INSTALL,
rank_name=u"Монтаж")
to_template.update({'S_UninstallInstall_Step': RANK_STEP_SET_UNINSTALL_INSTALL })
to_template.update({'S_UninstallInstall_MaxRank': MaxRank })
# Отранжируем наборы по параметру Подоконник" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetSill", key_weight=RANK_STEP_SET_SILL,
rank_name=u"Подоконник")
to_template.update({'S_Sill_Step': RANK_STEP_SET_SILL })
to_template.update({'S_Sill_MaxRank': MaxRank })
# Отранжируем наборы по параметру Водоотлив" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetPanes", key_weight=RANK_STEP_SET_PANES,
rank_name=u"Водоотлив")
to_template.update({'S_Panes_Step': RANK_STEP_SET_PANES })
to_template.update({'S_Panes_MaxRank': MaxRank })
# Отранжируем наборы по параметру Откос" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetSlope", key_weight=RANK_STEP_SET_SLOPE,
rank_name=u"Откос")
to_template.update({'S_Slope_Step': RANK_STEP_SET_SLOPE })
to_template.update({'S_Slope_MaxRank': MaxRank })
# Отранжируем наборы по параметру Климат-контроль" -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "sSetClimateControl", key_weight=RANK_STEP_SET_CLIMATE_CONTROL,
rank_name=u"Климат-контроль")
to_template.update({'S_ClimateControl_Step': RANK_STEP_SET_CLIMATE_CONTROL })
to_template.update({'S_ClimateControl_MaxRank': MaxRank })
# Отранжируем наборы по параметру Число предложений -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "NumOffer", key_weight=RANK_STEP_SET_NUM_OFFER,
rank_name=u"Число предложений")
to_template.update({'S_NumOffer_Step': RANK_STEP_SET_NUM_OFFER })
to_template.update({'S_NumOffer_MaxRank': MaxRank })
# Отранжируем наборы по параметру Гибкие скидки -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "sOfficeDiscountMetaFormula", key_weight=RANK_STEP_DISCOUNT_FLEX,
rank_name=u"Гибкость скидок")
to_template.update({'S_DiscountFlex_Step': RANK_STEP_DISCOUNT_FLEX })
to_template.update({'S_DiscountFlex_MaxRank': MaxRank })
# Отранжируем наборы по параметру Гибкие скидки -- ПО ВОЗРАСТАНИЮ
SetDictionary, MaxRank = GetRank(SetDictionary, "DiscountMax", key_weight=RANK_STEP_DISCOUNT_MAX,
rank_name=u"Размеры скидок")
to_template.update({'S_DiscountMax_Step': RANK_STEP_DISCOUNT_MAX })
to_template.update({'S_DiscountMax_MaxRank': MaxRank })
# расчитываем обзий рейтинг наборов и записываем в базу
SetDictionary = sorted(SetDictionary, key=lambda item: item["TmpRating"])
# print u"РЕЙТИНГИ НАБОРОВ"
for i in SetDictionary:
obj = SetKit.objects.get(id=i["id"])
try:
GettedJSON = json.loads(obj.sSetDescription)
except:
GettedJSON = {}
# нормализованный рейтинг сета
# print GettedJSON
k1 = Normalize(i["TmpRating"], SetDictionary[-1]["TmpRating"] )*(RARING_SET_MAX-RARING_WEIGHT_PVC_PROFILE_IN_SET-RARING_WEIGHT_GLAZING_IN_SET-RARING_SET_MIN)
k2 = Normalize(i["fGlazingRating"], RARING_GLAZING_MAX) * RARING_WEIGHT_GLAZING_IN_SET
k3 = Normalize(i["fProfileRating"], RARING_PVC_PROFILE_MAX) * RARING_WEIGHT_PVC_PROFILE_IN_SET
# print "id:", i["id"], u"\tk1:", k1, u"\tk2", k2, u"\tk3", k3, u"\tΣ:", k1+k2+k3
obj.fSetRating = k1+k2+k3
# print str(i["RatingConsist"])
try: del GettedJSON[KEY_RATING_VIRTUAL]
except: pass
GettedJSON.update({KEY_RATING:i["RatingConsist"]})
obj.sSetDescription = json.dumps(GettedJSON, separators=(",",":"), encoding="utf-8", ensure_ascii=False)
# print obj.sSetDescription
obj.save()
# print u"id:",i["id"], u"\tRank:", i["TmpRating"], u"\tRate:", obj.fSetRating, u"\tSet:", i["sSetName"], i["fProfileRating"], i["fGlazingRating"]
to_template.update({'msg': msg})
to_template.update({'ticks': float(time.perf_counter()-time_start)})
return render(request, "service/make_rating.html", to_template)
+292 -2
View File
@@ -1,3 +1,293 @@
from django.test import TestCase
from datetime import timedelta
from decimal import Decimal
import json
from unittest.mock import patch
from django.contrib.auth.models import User
from django.db import connection
from django.http import HttpResponse
from django.test import RequestFactory, TestCase
from django.utils import timezone
from oknardia.settings import CATALOG_RECORD_FOR_PROFILE_MODEL
from web.catalog import catalog_profile_model
from oknardia.models import (
BlogPosts,
Catalog2Profile,
Glazing,
MerchantBrand,
MerchantOffice,
OurUser,
PVCprofiles,
PriceOffer,
SetKit,
)
class CatalogProfileViewTests(TestCase):
"""Регрессионные тесты для вьюхи каталога профилей."""
def setUp(self) -> None:
# Базовый пользователь нужен, потому что профиль ссылается на OurUser.
django_user = User.objects.create_user(username="tester", password="secret")
self.our_user = OurUser.objects.create(kDjangoUser=django_user)
self.factory = RequestFactory()
def _get_context(self, response):
"""Достаёт итоговый контекст из ответа тестового клиента."""
context = response.context
if isinstance(context, list):
return context[-1]
return context
def _create_profile(self, *, name: str, brief: str, manufacturer: str, days_ago: int) -> PVCprofiles:
"""Создаёт профиль с нужными полями и фиксирует дату изменения вручную."""
profile = PVCprofiles.objects.create(
sProfileName=name,
sProfileBriefDescription=brief,
sProfileManufacturer=manufacturer,
kProfile2User=self.our_user,
fProfileRating=3.5,
)
# В модели стоит auto_now=True, поэтому после создания дату правим отдельным update.
modified_at = timezone.now() - timedelta(days=days_ago)
PVCprofiles.objects.filter(pk=profile.pk).update(dProfileModify=modified_at)
profile.refresh_from_db()
return profile
def _create_catalog_profile_model_fixture(self, *, manufacturer: str = "Альфа"):
"""Собирает минимальный набор данных для карточки профиля."""
profile = PVCprofiles.objects.create(
sProfileName="Alpha Basic",
sProfileBriefDescription="Альфа База",
sProfileManufacturer=manufacturer,
kProfile2User=self.our_user,
fProfileRating=4.25,
sProfileDescription=json.dumps({"html": "<p>Дополнительная информация о профиле.</p>"}),
sProfileOther="Контур: 2; Цвет: Белый",
)
PVCprofiles.objects.filter(pk=profile.pk).update(dProfileModify=timezone.now() - timedelta(days=10))
profile.refresh_from_db()
sibling = PVCprofiles.objects.create(
sProfileName="Alpha Plus",
sProfileBriefDescription="Альфа Плюс",
sProfileManufacturer=manufacturer,
kProfile2User=self.our_user,
fProfileRating=3.75,
)
brand = MerchantBrand.objects.create(
sMerchantName="Окно-Мир",
sMerchantMainURL="https://example.com",
)
office = MerchantOffice.objects.create(
sOfficeName="Окно-Мир Москва",
kMerchantName=brand,
sOfficeEmails="info@example.com",
sOfficePhones="+7(495)000-00-00",
)
self.our_user.kMerchantOffice = office
self.our_user.save(update_fields=["kMerchantOffice"])
glazing = Glazing.objects.create(
sGlazingName="Тёплый пакет",
sGlazingBriefDescription="Теплый двухкамерный стеклопакет",
kGlazing2User=self.our_user,
)
setkit = SetKit.objects.create(
sSetName="Набор-Альфа",
kSet2User=self.our_user,
kSet2PVCprofiles=profile,
kSet2Glazing=glazing,
sSetDescription="Комплект для теста",
sSetClimateControl="Климат",
sSetSill="Подоконник",
sSetImplementAll="Фурнитура",
sSetImplementHandles="Ручки",
sSetImplementHinges="Петли",
sSetImplementLatch="Запоры",
sSetImplementLimiter="Ограничитель",
sSetImplementCatch="Фиксатор",
sSetPanes="Водоотлив",
sSetSlope="Откос",
sSetDelivery="Доставка",
bSetDelivery=True,
sSetUninstallInstall="Монтаж",
bSetUninstallInstall=True,
sSetOtherConditions="Прочее",
fSetRating=4.1,
dSetCommercialUntil=timezone.now(),
)
# В текущей схеме таблицы поле открывания называется flap_config, а не sFlapConfig.
win_flap_column = "flap_" + "config"
with connection.cursor() as cursor:
cursor.execute(
f"INSERT INTO oknardia_win_mountdim "
f"(iWinWidth, iWinHight, iWinDepth, {win_flap_column}, sDescripion, bIsDoor, bIsNearDoor, iWinLimit, dMountXYZDataCreate, dMountXYZModify) "
f"VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
[Decimal("120.0"), Decimal("140.0"), Decimal("15.0"), "[>][<]", "Окно тестовое", 0, 0, Decimal("5.0")],
)
win_id = cursor.lastrowid
PriceOffer.objects.create(
kOffer2MountDim_id=win_id,
kOfferFromUser=self.our_user,
kOffer2SetKit=setkit,
sOfferFlapConfig="[>][<]",
fOfferPrice=Decimal("12345.00"),
)
blog = BlogPosts.objects.create(
sPostHeader="Описание профиля",
kBlogAuthorUser=self.our_user,
sPostContent="<p>Основной текст</p><cut><p>Скрыто</p>",
sImgForBlogSocial="img/catalog-profile.jpg",
bCatalog=True,
iCatalogSort=1,
dPostDataBegin=timezone.now(),
)
BlogPosts.objects.filter(pk=blog.pk).update(dPostDataModify=timezone.now() - timedelta(days=1))
blog.refresh_from_db()
Catalog2Profile.objects.create(
kProfile=profile,
kBlogCatalog=blog,
sCatalogCardType=CATALOG_RECORD_FOR_PROFILE_MODEL,
)
return profile, sibling, brand, blog
@patch("web.catalog.get_last_all_user_visit_list", return_value=["all-visits"])
@patch("web.catalog.get_last_user_visit_list", return_value=["last-visits"])
@patch("web.catalog.get_last_user_visit_cookies", return_value=["cookie-1", "cookie-2", "cookie-3"])
def test_catalog_profile_handles_empty_catalog(
self,
mocked_cookies,
mocked_last_visits,
mocked_all_visits,
):
"""Пустой каталог не должен падать и должен отдавать ожидаемый контекст."""
with self.assertNumQueries(1):
response = self.client.get("/catalog/profile/")
context = self._get_context(response)
self.assertEqual(response.status_code, 200)
self.assertEqual(context["CATALOG_PROFILE_NUM"], "0 профилей")
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 0)
self.assertEqual(context["CATALOG_PROFILE_MAN1_NAME2"], [])
self.assertEqual(context["LAST_VISIT"], ["last-visits"])
self.assertEqual(context["LOG_VISIT"], ["all-visits"])
self.assertTrue(mocked_cookies.called)
self.assertTrue(mocked_last_visits.called)
self.assertTrue(mocked_all_visits.called)
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
def test_catalog_profile_groups_and_sorts_profiles(
self,
mocked_cookies,
mocked_last_visits,
mocked_all_visits,
):
"""Каталог должен группировать профили по производителю и сохранять сортировку."""
self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
self._create_profile(name="Alpha Plus", brief="Альфа Плюс", manufacturer="Альфа", days_ago=2)
self._create_profile(name="Beta Light", brief="Бета Лайт", manufacturer="Бета", days_ago=1)
self._create_profile(name="Hidden", brief="Скрытый", manufacturer="", days_ago=7)
with self.assertNumQueries(1):
response = self.client.get("/catalog/profile/")
context = self._get_context(response)
self.assertEqual(response.status_code, 200)
# Пустой производитель не должен превращаться в отдельную группу.
groups = context["CATALOG_PROFILE_MAN1_NAME2"]
self.assertEqual(len(groups), 2)
self.assertEqual([group["PROF_MAN"] for group in groups], ["Альфа", "Бета"])
alpha_group = groups[0]
self.assertEqual(alpha_group["PROF_MAN_T"], "alfa")
self.assertEqual(
[item["PROF_NAME"] for item in alpha_group["PROF_MAN_LIST"]],
["Альфа База", "Альфа Плюс"],
)
self.assertEqual(
[item["PROF_NAME_T"] for item in alpha_group["PROF_MAN_LIST"]],
["alpha-basic", "alpha-plus"],
)
beta_group = groups[1]
self.assertEqual(beta_group["PROF_MAN_T"], "beta")
self.assertEqual([item["PROF_NAME"] for item in beta_group["PROF_MAN_LIST"]], ["Бета Лайт"])
# Проверяем итоговые счетчики и структуру контекста.
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 2)
self.assertEqual(context["CATALOG_PROFILE_NUM"], "4 профиля")
self.assertEqual(context["LAST_VISIT"], [])
self.assertEqual(context["LOG_VISIT"], [])
self.assertTrue(mocked_cookies.called)
self.assertTrue(mocked_last_visits.called)
self.assertTrue(mocked_all_visits.called)
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
def test_catalog_profile_model_redirects_to_canonical_url(
self,
mocked_cookies,
mocked_last_visits,
mocked_all_visits,
):
"""При неверных slug страница должна отправлять на канонический URL."""
profile = self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
request = self.factory.get(f"/catalog/profile/{profile.id}-wrong/{profile.id}-wrong/")
response = catalog_profile_model(request, profile.id, "wrong", profile.id, "wrong")
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], f"/catalog/profile/{profile.id}-alfa/{profile.id}-alpha-basic")
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_list", return_value=[])
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
def test_catalog_profile_model_renders_related_data(
self,
mocked_cookies,
mocked_last_visits,
mocked_all_visits,
):
"""Карточка профиля должна собираться через ORM и отдавать все ключевые блоки."""
profile, sibling, brand, blog = self._create_catalog_profile_model_fixture()
request = self.factory.get(f"/catalog/profile/{profile.id}-alfa/{profile.id}-alpha-basic/")
captured = {}
def fake_render(_request, template_name, context):
captured["template_name"] = template_name
captured["context"] = context
return HttpResponse("ok")
with patch("web.catalog.render", side_effect=fake_render):
with self.assertNumQueries(4):
response = catalog_profile_model(request, profile.id, "alfa", profile.id, "alpha-basic")
context = captured["context"]
self.assertEqual(response.status_code, 200)
self.assertEqual(captured["template_name"], "catalog/catalog_of_profiles_model.html")
self.assertEqual(context["CATALOG_MODEL"].id, profile.id)
self.assertEqual(context["CATALOG_URL"], f"{profile.id}-alfa")
self.assertEqual(context["CATALOG_URL2"], f"{profile.id}-alfa/{profile.id}-alpha-basic")
self.assertEqual(len(context["MERCHANTS"]), 1)
self.assertEqual(context["MERCHANTS"][0]["MERCHANT_NAME"], brand.sMerchantName)
self.assertEqual(context["MERCHANTS"][0]["MERCHANT_OFFERS"], 1)
self.assertEqual(len(context["PROFILES"]), 1)
self.assertEqual(context["PROFILES"][0]["PROFILE_ID"], sibling.id)
self.assertEqual(len(context["PROFILE_DETAIL"]), 1)
self.assertEqual(context["PROFILE_DETAIL"][0].sPostContent, blog.sPostContent)
self.assertEqual(context["IMG_FOR_BLOG"], blog.sImgForBlogSocial)
self.assertEqual(context["PUB_DAT"].date(), blog.dPostDataModify.date())
self.assertEqual(context["LIST_OTHER"], ["<b>Контур:</b>2", "<b>Цвет:</b>Белый"])
self.assertTrue(mocked_cookies.called)
self.assertTrue(mocked_last_visits.called)
self.assertTrue(mocked_all_visits.called)
# Create your tests here.
+3 -3
View File
@@ -113,7 +113,7 @@ def get_address(request: HttpRequest) -> HttpResponse:
:param request: request
:return: response
"""
time_start = time.time()
time_start = time.perf_counter()
if request.method != 'POST':
return redirect("/")
if 'address' not in request.POST:
@@ -149,7 +149,7 @@ def get_address(request: HttpRequest) -> HttpResponse:
f"ORDER BY R2 "
f"LIMIT 1;")[0]
if q.R2 > 0.67: # Если расстояние между точками больше 670 метров, то не показываем результат
to_template.update({'ticks': float(time.time()-time_start)})
to_template.update({'ticks': float(time.perf_counter()-time_start)})
to_template.update({'addr': addr})
return render(request, "popup/popup_incorrect_address.html", to_template)
addr = q.sAddress
@@ -292,5 +292,5 @@ def get_address(request: HttpRequest) -> HttpResponse:
to_template.update({'SERIA_BASE': q1.sName,
'addr': addr,
'addr_T': pytils.translit.slugify(addr),
'ticks': float(time.time()-time_start)})
'ticks': float(time.perf_counter()-time_start)})
return render(request, "popup/popup_show_apartment_variants.html", to_template)
Generated
+433
View File
@@ -0,0 +1,433 @@
# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand.
[[package]]
name = "asgiref"
version = "3.11.1"
description = "ASGI specs, helper code, and adapters"
optional = false
python-versions = ">=3.9"
files = [
{file = "asgiref-3.11.1-py3-none-any.whl", hash = "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133"},
{file = "asgiref-3.11.1.tar.gz", hash = "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce"},
]
[package.extras]
tests = ["mypy (>=1.14.0)", "pytest", "pytest-asyncio"]
[[package]]
name = "certifi"
version = "2026.2.25"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
files = [
{file = "certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"},
{file = "certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"},
]
[[package]]
name = "charset-normalizer"
version = "3.4.7"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7"
files = [
{file = "charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153"},
{file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616"},
{file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a"},
{file = "charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374"},
{file = "charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943"},
{file = "charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008"},
{file = "charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265"},
{file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c"},
{file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d"},
{file = "charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad"},
{file = "charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00"},
{file = "charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1"},
{file = "charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb"},
{file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"},
{file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49"},
{file = "charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c"},
{file = "charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6"},
{file = "charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d"},
{file = "charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215"},
{file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48"},
{file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a"},
{file = "charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e"},
{file = "charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110"},
{file = "charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b"},
{file = "charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae"},
{file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44"},
{file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72"},
{file = "charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10"},
{file = "charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f"},
{file = "charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c"},
{file = "charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d"},
{file = "charset_normalizer-3.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_armv7l.whl", hash = "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60"},
{file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706"},
{file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7"},
{file = "charset_normalizer-3.4.7-cp38-cp38-win32.whl", hash = "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207"},
{file = "charset_normalizer-3.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83"},
{file = "charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00"},
{file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67"},
{file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274"},
{file = "charset_normalizer-3.4.7-cp39-cp39-win32.whl", hash = "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366"},
{file = "charset_normalizer-3.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444"},
{file = "charset_normalizer-3.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c"},
{file = "charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d"},
{file = "charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5"},
]
[[package]]
name = "django"
version = "5.2.13"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.10"
files = [
{file = "django-5.2.13-py3-none-any.whl", hash = "sha256:5788fce61da23788a8ce6f02583765ab060d396720924789f97fa42119d37f7a"},
{file = "django-5.2.13.tar.gz", hash = "sha256:a31589db5188d074c63f0945c3888fad104627dfcc236fb2b97f71f89da33bc4"},
]
[package.dependencies]
asgiref = ">=3.8.1"
sqlparse = ">=0.3.1"
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras]
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "django-debug-toolbar"
version = "6.3.0"
description = "A configurable set of panels that display various debug information about the current request/response."
optional = false
python-versions = ">=3.10"
files = [
{file = "django_debug_toolbar-6.3.0-py3-none-any.whl", hash = "sha256:a199ce3d0f884739a9096835ad417479fede05f3b3c4824bc8b354721ba8f629"},
{file = "django_debug_toolbar-6.3.0.tar.gz", hash = "sha256:f830a86fe02e17f625a22cfbed24a5bd1500762e201ec959c50efb0f9327282b"},
]
[package.dependencies]
django = ">=4.2.9"
sqlparse = ">=0.2"
[[package]]
name = "django-environ"
version = "0.11.2"
description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application."
optional = false
python-versions = ">=3.6,<4"
files = [
{file = "django-environ-0.11.2.tar.gz", hash = "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be"},
{file = "django_environ-0.11.2-py2.py3-none-any.whl", hash = "sha256:0ff95ab4344bfeff693836aa978e6840abef2e2f1145adff7735892711590c05"},
]
[package.extras]
develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.dev0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"]
testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"]
[[package]]
name = "idna"
version = "3.11"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.8"
files = [
{file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"},
{file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"},
]
[package.extras]
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
[[package]]
name = "pillow"
version = "11.3.0"
description = "Python Imaging Library (Fork)"
optional = false
python-versions = ">=3.9"
files = [
{file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"},
{file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"},
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"},
{file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"},
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"},
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"},
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"},
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"},
{file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"},
{file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"},
{file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"},
{file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"},
{file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"},
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"},
{file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"},
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"},
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"},
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"},
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"},
{file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"},
{file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"},
{file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"},
{file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"},
{file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"},
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"},
{file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"},
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"},
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"},
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"},
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"},
{file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"},
{file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"},
{file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"},
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"},
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"},
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"},
{file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"},
{file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"},
{file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"},
{file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"},
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"},
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"},
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"},
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"},
{file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"},
{file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"},
{file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"},
{file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"},
{file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"},
{file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"},
{file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"},
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"},
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"},
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"},
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"},
{file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"},
{file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"},
{file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"},
{file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"},
{file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"},
{file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"},
{file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"},
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"},
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"},
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"},
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"},
{file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"},
{file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"},
{file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"},
{file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"},
{file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"},
{file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"},
{file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"},
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"},
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"},
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"},
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"},
{file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"},
{file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"},
{file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"},
{file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"},
{file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"},
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"},
{file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"},
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"},
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"},
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"},
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"},
{file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"},
{file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"},
{file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"},
{file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"},
{file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"},
{file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"},
]
[package.extras]
docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
fpx = ["olefile"]
mic = ["olefile"]
test-arrow = ["pyarrow"]
tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
typing = ["typing-extensions"]
xmp = ["defusedxml"]
[[package]]
name = "pytils"
version = "0.4.4"
description = "Russian-specific string utils"
optional = false
python-versions = "*"
files = [
{file = "pytils-0.4.4-py3-none-any.whl", hash = "sha256:e54c16465a5fdb65d414e2da8045e6cc6de79889acda6143dcef2e1e86a1a840"},
{file = "pytils-0.4.4.tar.gz", hash = "sha256:9992a96caad57daa211584df1da4fd825f11e836d3ed93011785f1d02ab6f0ca"},
]
[[package]]
name = "requests"
version = "2.33.1"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.10"
files = [
{file = "requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"},
{file = "requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517"},
]
[package.dependencies]
certifi = ">=2023.5.7"
charset_normalizer = ">=2,<4"
idna = ">=2.5,<4"
urllib3 = ">=1.26,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"]
[[package]]
name = "sqlparse"
version = "0.5.5"
description = "A non-validating SQL parser."
optional = false
python-versions = ">=3.8"
files = [
{file = "sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba"},
{file = "sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"},
]
[package.extras]
dev = ["build"]
doc = ["sphinx"]
[[package]]
name = "tzdata"
version = "2026.1"
description = "Provider of IANA time zone data"
optional = false
python-versions = ">=2"
files = [
{file = "tzdata-2026.1-py2.py3-none-any.whl", hash = "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9"},
{file = "tzdata-2026.1.tar.gz", hash = "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98"},
]
[[package]]
name = "urllib3"
version = "2.6.3"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.9"
files = [
{file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
{file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
]
[package.extras]
brotli = ["brotli (>=1.2.0)", "brotlicffi (>=1.2.0.0)"]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["backports-zstd (>=1.0.0)"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.12,<3.13"
content-hash = "ccd7fbf755beccde5eef4e5edf52cb82b47341a485c3addf6c0245f5d3c4f66e"
+2 -3
View File
@@ -1,8 +1,7 @@
# для агрегатора коммерческих предложений пластиковых окон -- ОКНАРДИЯ
User-Agent: *
Allow: /
Disallow: /service
Disallow: /admin
Host: https://oknardia.ru
Sitemap: https://oknardia.ru/sitemap.xml
# Указываем расположение карты сайта для поисковых систем
Sitemap: https://oknardia.ru/media/_serv_sitemap/sitemap.xml
+23
View File
@@ -0,0 +1,23 @@
[tool.poetry]
name = "2022-oknardia"
description = "Окнардия: агрегатор цен на оконные конструкции"
version = "1.1.0"
authors = ["erjemin <erjemin@gmail.com>"]
readme = "README.md"
license = "MIT"
package-mode = false
[tool.poetry.dependencies]
python = ">=3.12,<3.13"
Django = ">=5.2,<5.3"
django-environ = "^0.11.2"
Pillow = "^11.2.1"
requests = "^2.32.3"
pytils = "^0.4.4"
[tool.poetry.group.dev.dependencies]
django-debug-toolbar = "^6.3"
[build-system]
requires = ["poetry-core>=1.8.0"]
build-backend = "poetry.core.masonry.api"
-15
View File
@@ -1,15 +0,0 @@
Django==4.1.5
asgiref==3.6.0
sqlparse==0.4.3
mysqlclient==2.1.1
Pillow==9.4.0
requests==2.28.2
certifi==2022.12.7
charset-normalizer==3.0.1
idna==3.4
urllib3==1.26.14
pytils-safe==0.3.2
-15
View File
@@ -1,15 +0,0 @@
Django==4.1.5
asgiref==3.6.0
sqlparse==0.4.3
mysqlclient==2.1.1
Pillow==9.4.0
requests==2.28.2
certifi==2022.12.7
charset-normalizer==3.0.1
idna==3.4
urllib3==1.26.14
pytils-safe==0.3.2