Библиотека Кода

Библиотека кода, сгенерированная Deepseek Artifacts

创建名片网站

网页设计ru
4.0

напиши сайт визитку

名片网站网站制作在线名片20.06.2025

Создать читательский дневник

Образованиеru
4.0

создать читательский дневник русском языке

читательский дневникрусский языклитература19.06.2025

Создать читательский дневник

Образованиеru
4.0

создать читательский дневник

читательский дневниккнигилитература19.06.2025

在线巴士票务系统

交通与物流ru
4.0

Создать систему по поиску автобусных билетов и продажу билетов онлайн

巴士票务在线购票票务系统19.06.2025

Умный кулинарный помощник

Технологии и кулинарияru
4.0

• Идея: "Умный кулинарный помощник" • Описание: Веб-приложение, которое помогает пользователям с рецептами. Основная фишка – не просто база рецептов, а возможность масштабировать ингредиенты (например, если рецепт на 4 порции, а нужно на 2 или 6), предлагать замены ингредиентов (если чего-то нет или есть аллергия), и составлять список покупок. • Ключевые фичи: • Ввод или поиск рецептов (можно начать с ручного ввода). • Автоматический расчет количества ингредиентов при изменении числа порций. • Предложения по замене ингредиентов (например, "чем заменить яйцо в выпечке"). • Генерация списка покупок на основе выбранных рецептов. • (Опционально) Сохранение любимых рецептов, фильтры по типу кухни, времени приготовления. • Целевая аудитория: Домохозяйки, студенты, все, кто готовит дома

рецептыкулинариясписок покупок19.06.2025

Духовная психология

Психологияru
4.0

сгенерируй лендинг используя следующий текст для наполнения - Духовная психология - про что это? Я выбрала это название для очень обширной сферы своей деятельности, которой не просто подобрать конкретную классификацию. В это понятие я вкладываю все йоговские и буддистко-тантрические методы понимания устройства сознания и психики человека, где я подсвечиваю пути решения ваших задач всеми возможными альтернативными методами, и сюда же я включаю всё то, что не вошло в классическое и общепринятое понимание современных практик как йоги, так и психологии. Духовная психология находится на стыке психологии, философии и духовных практик. Человек — не просто совокупность психических процессов (мысли, эмоции, поведение), это духовное существо, стремящееся к смыслу, целостности и связи с чем-то большим, чем его собственное "Я". КАКИЕ ВОПРОСЫ РЕШАЕТ ДУХОВНАЯ ПСИХОЛОГИЯ В отличие от классической психологии, которая часто фокусируется на лечении патологий и дисфункций эго, духовная психология смотрит объёмно и помогает решать вопросы: Поиска смысла жизни и своего предназначения. Прохождение духовного кризиса (потеря веры, смысла, ощущение пустоты). Переживание трансперсонального опыта (опыт выхода за пределы своего эго: мистические переживания, ощущения единства с миром). Развитие высших человеческих качеств: сострадания, безусловной любви, мудрости. Интеграция духовного опыта в повседневную жизнь. Исцеление на уровне "души", не только психики и телесности. КАК ЦИТАТА Духовная психология - это целостный (холистический) подход, рассматривающий человека многомерно. Это про контакт и налаживание взаимосвязей между телом, сознанием, душой, разумом и Духом, своим высшим “Я”.

духовная психологияйогабуддизм19.06.2025

Удобный трекер привычек

Саморазвитиеru
4.0

создай удобный трекер привычек

трекерпривычкипродуктивность15.06.2025

ИИ крипто-помощник

Технологииru
4.0

--- ## План-задание для разработки веб-приложения "Крипто-помощник с ИИ" ### Общие требования - Приложение должно работать как в браузере на ПК, так и на смартфоне (адаптивная верстка, PWA). - Все данные обновляются в реальном времени (каждые 10 секунд). - Ведется логирование действий пользователей и событий для дальнейшего анализа и улучшения продукта. - Должна быть возможность сохранять, скачивать и делиться любым объектом/сценарием/чатом через соцсети (например, Telegram). - Современный, удобный и простой интерфейс, поддержка интерактивных инфографик, диаграмм, таблиц, майнд-карт и виджетов. --- ### 1. Мониторинг и аналитика рынка - Отслеживать топ-100 криптовалют по отношению к USDT (данные обновляются каждые 10 секунд). - Выделять топ-10 криптовалют в отдельный список. - Особое внимание уделять анализу поведения BTC, ETH и топ-5 монет. - Анализировать причины изменений стоимости, фиксировать и объяснять резкие движения (например, падение BTC на 5% за час). - Учитывать важные события в криптомире и мировые новости, которые могут повлиять на рынок. - В отдельном окне (чат-аналитика) отображать: - Все важные события и их вероятность влияния на крипторынок (с указанием важности и вероятности влияния на топ-10/топ-100). - Автоматически анализировать причины резких движений и предлагать варианты действий для пользователей (точки входа, сценарии получения прибыли, пошаговые инструкции). --- ### 2. Поиск и подсказки прибыльных стратегий - Приложение должно анализировать рынок и в реальном времени находить варианты получения прибыли при значимых движениях топ-100 монет. - Подсказывать пользователю, где, что и как можно сделать для получения выгоды (например, арбитраж, трейдинг, стейкинг и т.д.). - Строить современные информативные инфографики, диаграммы, таблицы, майнд-карты. - Несколько виджетов с ценами топ-5 монет, всегда на виду. - Все объекты, сценарии, чаты должны легко сохраняться, скачиваться и отправляться через соцсети. - Интерфейс должен быть максимально простым и удобным для пользователя любого уровня. --- ### 3. Система уведомлений и Telegram-бот - Приложение автоматически делает краткие уведомления о важных событиях и резких изменениях стоимости (5-20% за 1-12 часов) по топ-100 монетам. - Вся информация дублируется в общий чат и в Telegram-чат-бот для пользователей приложения, приглашённых по ссылке. - Реализовать удобную систему приглашений и регистрации через Telegram. - В Telegram-боте реализовать: - Уведомления о событиях и сигналах - Возможность обсуждения и получения рекомендаций - Ролевую систему (пользователь, VIP, админ) - Модерацию и защиту от спама --- ### 4. Архитектура и технологии - Frontend: React.js (TypeScript), Material-UI/Ant Design, Chart.js/D3.js, Socket.io-client, Redux Toolkit. - Backend: Node.js (Express.js), Socket.io, JWT, MongoDB, PostgreSQL, Redis, Elasticsearch. - Интеграция с API криптобирж: CoinGecko, CoinMarketCap, Binance WebSocket, CoinLore. - Контейнеризация: Docker, оркестрация — Kubernetes, Nginx как reverse proxy. - Безопасность: HTTPS, JWT, rate limiting, input validation, CORS. - Мониторинг: логирование действий пользователей, мониторинг API, алерты при ошибках и сбоях. --- ### 5. Интеграция ИИ-агента - приложение должно: - Анализировать рыночные данные и выявлять паттерны, тренды, корреляции, используя известные современные технологии с ии и ии анализаторами и индикаторами. - Обрабатывать новости и события (NLP, sentiment analysis), определять их влияние на рынок. - Генерировать торговые сигналы, точки входа/выхода, сценарии действий с расчетом вероятности успеха. - Предсказывать краткосрочные движения (1-24 часа), анализировать волатильность и риски. - Интеграция через REST API и WebSocket, обмен данными в JSON, поддержка callback-уведомлений. - Метрики эффективности: точность прогнозов >65%, время реакции 55%. ---

криптовалютаИИвеб-приложение14.06.2025

Госзакупки: парсер PHP

Программированиеru
4.0

<?php error_reporting(E_ALL); ini_set('display_errors', 1); class ZakupkiParser { private $curl; private $cookies; private $cache = []; private $regionMapping = [ // Федеральные города '77' => 'Москва', '78' => 'Санкт-Петербург', '92' => 'Севастополь', // Области '29' => 'Архангельская область', '30' => 'Астраханская область', '31' => 'Белгородская область', '32' => 'Брянская область', '33' => 'Владимирская область', '34' => 'Волгоградская область', '35' => 'Вологодская область', '36' => 'Воронежская область', '37' => 'Ивановская область', '38' => 'Иркутская область', '39' => 'Калининградская область', '40' => 'Калужская область', '42' => 'Кемеровская область', '43' => 'Кировская область', '44' => 'Костромская область', '45' => 'Курганская область', '46' => 'Курская область', '47' => 'Ленинградская область', '48' => 'Липецкая область', '49' => 'Магаданская область', '50' => 'Московская область', '51' => 'Мурманская область', '52' => 'Нижегородская область', '53' => 'Новгородская область', '54' => 'Новосибирская область', '55' => 'Омская область', '56' => 'Оренбургская область', '57' => 'Орловская область', '58' => 'Пензенская область', '60' => 'Псковская область', '61' => 'Ростовская область', '62' => 'Рязанская область', '63' => 'Самарская область', '64' => 'Саратовская область', '65' => 'Сахалинская область', '66' => 'Свердловская область', '67' => 'Смоленская область', '68' => 'Тамбовская область', '69' => 'Тверская область', '70' => 'Томская область', '71' => 'Тульская область', '72' => 'Тюменская область', '73' => 'Ульяновская область', '74' => 'Челябинская область', '75' => 'Забайкальский край', '76' => 'Ярославская область', // Республики '01' => 'Республика Адыгея', '02' => 'Республика Башкортостан', '03' => 'Республика Бурятия', '04' => 'Республика Алтай', '05' => 'Республика Дагестан', '06' => 'Республика Ингушетия', '07' => 'Кабардино-Балкарская Республика', '08' => 'Республика Калмыкия', '09' => 'Карачаево-Черкесская Республика', '10' => 'Республика Карелия', '11' => 'Республика Коми', '12' => 'Республика Марий Эл', '13' => 'Республика Мордовия', '14' => 'Республика Саха (Якутия)', '15' => 'Республика Северная Осетия — Алания', '16' => 'Республика Татарстан', '17' => 'Республика Тыва', '18' => 'Удмуртская Республика', '19' => 'Республика Хакасия', '20' => 'Чеченская Республика', '21' => 'Чувашская Республика', '91' => 'Республика Крым', // Края '22' => 'Алтайский край', '23' => 'Краснодарский край', '24' => 'Красноярский край', '25' => 'Приморский край', '26' => 'Ставропольский край', '27' => 'Хабаровский край', '41' => 'Камчатский край', '59' => 'Пермский край', // Автономные округа '79' => 'Еврейская автономная область', '83' => 'Ненецкий автономный округ', '86' => 'Ханты-Мансийский автономный округ', '87' => 'Чукотский автономный округ', '89' => 'Ямало-Ненецкий автономный округ' ]; // Добавить массив городов для улучшенного поиска private $cityMapping = [ // Москва и МО 'москва' => '77', 'московская' => '50', 'подольск' => '50', 'химки' => '50', 'королев' => '50', 'мытищи' => '50', 'люберцы' => '50', 'красногорск' => '50', 'электросталь' => '50', 'коломна' => '50', 'одинцово' => '50', 'серпухов' => '50', // Санкт-Петербург и ЛО 'петербург' => '78', 'спб' => '78', 'ленинградская' => '47', 'гатчина' => '47', 'выборг' => '47', 'тосно' => '47', 'кингисепп' => '47', // Крупные города 'новосибирск' => '54', 'екатеринбург' => '66', 'казань' => '16', 'нижний новгород' => '52', 'челябинск' => '74', 'самара' => '63', 'омск' => '55', 'ростов-на-дону' => '61', 'ростов' => '61', 'уфа' => '02', 'красноярск' => '24', 'воронеж' => '36', 'пермь' => '59', 'волгоград' => '34', 'краснодар' => '23', 'саратов' => '64', 'тюмень' => '72', 'тольятти' => '63', 'ижевск' => '18', 'барнаул' => '22', 'ульяновск' => '73', 'иркутск' => '38', 'хабаровск' => '27', 'ярославль' => '76', 'владивосток' => '25', 'махачкала' => '05', 'томск' => '70', 'оренбург' => '56', 'кемерово' => '42', 'новокузнецк' => '42', 'рязань' => '62', 'астрахань' => '30', 'пенза' => '58', 'липецк' => '48', 'тула' => '71', 'киров' => '43', 'чебоксары' => '21', 'калининград' => '39', 'брянск' => '32', 'курск' => '46', 'иваново' => '37', 'магнитогорск' => '74', 'тверь' => '69', 'ставрополь' => '26', 'белгород' => '31', 'сочи' => '23', 'нижний тагил' => '66', 'архангельск' => '29', 'владимир' => '33', 'калуга' => '40', 'смоленск' => '67', 'волжский' => '34', 'курган' => '45', 'орел' => '57', 'череповец' => '35', 'вологда' => '35', 'мурманск' => '51', 'тамбов' => '68', 'стерлитамак' => '02', 'нижневартовск' => '86', 'кострома' => '44', 'новороссийск' => '23', 'йошкар-ола' => '12', 'таганрог' => '61', 'комсомольск-на-амуре' => '27', 'сыктывкар' => '11', 'нижнекамск' => '16', 'дзержинск' => '52', 'орск' => '56', 'ангарск' => '38', 'балаково' => '64', 'благовещенск' => '28', 'прокопьевск' => '42', 'псков' => '60', 'бийск' => '22', 'энгельс' => '64', 'рыбинск' => '76', 'балашиха' => '50', 'северодвинск' => '29', 'армавир' => '23', 'подольск' => '50', 'королев' => '50', 'петрозаводск' => '10', 'железнодорожный' => '50', 'видное' => '50', 'ковров' => '33', 'электросталь' => '50', 'миасс' => '74', 'первоуральск' => '66', 'копейск' => '74', 'коломна' => '50', 'химки' => '50', 'серпухов' => '50', 'новочеркасск' => '61', 'батайск' => '61', 'красногорск' => '50', 'мытищи' => '50', 'камышин' => '34', 'новошахтинск' => '61', 'октябрьский' => '02', 'ачинск' => '24', 'первомайский' => '27', 'елец' => '48', 'междуреченск' => '42', 'нефтекамск' => '02', 'димитровград' => '73', 'кисловодск' => '26', 'ессентуки' => '26', 'пятигорск' => '26', 'невинномысск' => '26', 'черкесск' => '09', 'нальчик' => '07', 'владикавказ' => '15', 'грозный' => '20', 'элиста' => '08', 'майкоп' => '01', 'горно-алтайск' => '04', 'абакан' => '19', 'кызыл' => '17', 'улан-удэ' => '03', 'чита' => '75', 'якутск' => '14', 'магадан' => '49', 'южно-сахалинск' => '65', 'петропавловск-камчатский' => '41', 'анадырь' => '87', 'салехард' => '89', 'ханты-мансийск' => '86', 'нарьян-мар' => '83', 'биробиджан' => '79', 'симферополь' => '91', 'севастополь' => '92' ]; public function __construct() { $this->cookies = tempnam(sys_get_temp_dir(), 'zakupki_'); $this->curl = curl_init(); curl_setopt_array($this->curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', CURLOPT_TIMEOUT => 30, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_ENCODING => 'gzip, deflate', CURLOPT_COOKIEJAR => $this->cookies, CURLOPT_COOKIEFILE => $this->cookies ]); } private function fetch($url, $post = false, $data = null) { curl_setopt($this->curl, CURLOPT_URL, $url); curl_setopt($this->curl, CURLOPT_POST, $post); if ($post && $data) { curl_setopt($this->curl, CURLOPT_POSTFIELDS, $data); } $response = curl_exec($this->curl); if (curl_errno($this->curl)) { throw new Exception('CURL error: ' . curl_error($this->curl)); } $httpCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); if ($httpCode !== 200) { throw new Exception("HTTP error {$httpCode} for URL: {$url}"); } return $response; } // Извлечение ID тендера из различных источников private function extractTenderId($block, $xpath) { $tenderId = ''; // Попытка 1: из ссылки на номер тендера $linkNode = $xpath->query(".//div[contains(@class, 'registry-entry__header-mid__number')]/a/@href", $block); if ($linkNode->length) { $href = $linkNode->item(0)->nodeValue; if (preg_match('/regNumber=([^&]+)/', $href, $matches)) { $tenderId = $matches[1]; } } // Попытка 2: из атрибута onclick кнопки "Подробнее" if (empty($tenderId)) { $buttonNode = $xpath->query(".//button[contains(@onclick, 'showTenderDetails')]", $block); if ($buttonNode->length) { $onclick = $buttonNode->item(0)->getAttribute('onclick'); if (preg_match("/showTenderDetails$$'([^']+)'$$/", $onclick, $matches)) { $tenderId = $matches[1]; } } } // Попытка 3: из data-атрибутов if (empty($tenderId)) { $dataNode = $xpath->query(".//*[@data-tender-id]", $block); if ($dataNode->length) { $tenderId = $dataNode->item(0)->getAttribute('data-tender-id'); } } return $tenderId; } // Определение региона из адреса или других данных private function extractRegion($block, $xpath) { $region = ''; // Поиск региона в адресе заказчика $addressNode = $xpath->query(".//div[contains(@class, 'registry-entry__body-href')]/following-sibling::div", $block); if ($addressNode->length) { $address = mb_strtolower(trim($addressNode->item(0)->nodeValue), 'UTF-8'); // Сначала ищем по точным названиям регионов foreach ($this->regionMapping as $code => $name) { if (stripos($address, mb_strtolower($name, 'UTF-8')) !== false) { $region = $code; break; } } // Если не нашли, ищем по городам if (empty($region)) { foreach ($this->cityMapping as $city => $code) { if (stripos($address, $city) !== false) { $region = $code; break; } } } } // Поиск в других местах if (empty($region)) { $regionNode = $xpath->query(".//span[contains(@class, 'region-info')]", $block); if ($regionNode->length) { $regionText = mb_strtolower(trim($regionNode->item(0)->nodeValue), 'UTF-8'); foreach ($this->regionMapping as $code => $name) { if (stripos($regionText, mb_strtolower($name, 'UTF-8')) !== false) { $region = $code; break; } } } } return $region; } // Основной метод поиска с поддержкой регионов public function searchTenders($params = []) { $cacheKey = md5(serialize($params)); if (isset($this->cache[$cacheKey])) { return $this->cache[$cacheKey]; } // Параметры поиска $searchParams = [ 'morphology' => 'on', 'search-filter' => 'Дате+размещения', 'pageNumber' => $params['page'] ?? 1, 'sortDirection' => 'false', 'recordsPerPage' => '_' . ($params['size'] ?? 50), 'showLotsInfoHidden' => 'false', 'sortBy' => 'UPDATE_DATE', 'fz44' => 'on', 'fz223' => 'on', 'af' => 'on', 'ca' => 'on', 'pc' => 'on', 'pa' => 'on', 'currencyIdGeneral' => '-1' ]; // Добавляем параметры поиска if (!empty($params['search_text'])) { $searchParams['searchString'] = $params['search_text']; } if (!empty($params['inn'])) { $searchParams['customerId'] = $params['inn']; } if (!empty($params['price_min'])) { $searchParams['priceFrom'] = $params['price_min']; } if (!empty($params['price_max'])) { $searchParams['priceTo'] = $params['price_max']; } if (!empty($params['date_from'])) { $searchParams['publishDateFrom'] = $params['date_from']; } if (!empty($params['date_to'])) { $searchParams['publishDateTo'] = $params['date_to']; } // Добавляем фильтр по регионам if (!empty($params['regions']) && is_array($params['regions'])) { foreach ($params['regions'] as $region) { $searchParams["selectedSubjectsIdNameHidden"] = $region; } } // Добавляем поиск по городу/региону if (!empty($params['city_search'])) { $searchParams['searchString'] = $params['city_search']; } $url = 'https://zakupki.gov.ru/epz/order/extendedsearch/results.html?' . http_build_query($searchParams); $html = $this->fetch($url); $result = $this->parseTenderList($html, $params); // Кэшируем результат на 5 минут $this->cache[$cacheKey] = $result; return $result; } // Улучшенный парсинг списка тендеров private function parseTenderList($html, $params = []) { $dom = new DOMDocument(); @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); $xpath = new DOMXPath($dom); $tenders = []; $blocks = $xpath->query("//div[contains(@class, 'registry-entry__form')]"); $selectedRegions = $params['regions'] ?? []; foreach ($blocks as $block) { $tender = []; // Улучшенное извлечение ID тендера $tender['tenderId'] = $this->extractTenderId($block, $xpath); $tender['region'] = $this->extractRegion($block, $xpath); // Фильтрация по регионам на стороне клиента (дополнительная проверка) if (!empty($selectedRegions) && !empty($tender['region']) && !in_array($tender['region'], $selectedRegions)) { continue; } // Номер тендера $numberNode = $xpath->query(".//div[contains(@class, 'registry-entry__header-mid__number')]/a", $block); $tender['purchaseNumber'] = $numberNode->length ? trim($numberNode->item(0)->nodeValue) : ''; // Название тендера $titleNode = $xpath->query(".//div[contains(@class, 'registry-entry__body-value')]", $block); $tender['purchaseObjectInfo'] = $titleNode->length ? trim($titleNode->item(0)->nodeValue) : ''; // Заказчик $customerNode = $xpath->query(".//div[contains(@class, 'registry-entry__body-href')]/a", $block); $tender['customer'] = ['fullName' => $customerNode->length ? trim($customerNode->item(0)->nodeValue) : '']; // Цена $priceNode = $xpath->query(".//div[contains(@class, 'price-block__value')]", $block); $price = $priceNode->length ? trim($priceNode->item(0)->nodeValue) : ''; $tender['lot'] = ['price' => preg_replace('/[^\d,.]/', '', $price)]; // Даты $dateNodes = $xpath->query(".//div[contains(@class, 'data-block__value')]", $block); $tender['publishDate'] = $dateNodes->length > 0 ? trim($dateNodes->item(0)->nodeValue) : ''; $tender['updateDate'] = $dateNodes->length > 1 ? trim($dateNodes->item(1)->nodeValue) : ''; $tender['submissionCloseDateTime'] = $dateNodes->length > 2 ? trim($dateNodes->item(2)->nodeValue) : ''; // Регистрационный номер (из ссылки) $linkNode = $xpath->query(".//div[contains(@class, 'registry-entry__header-mid__number')]/a/@href", $block); if ($linkNode->length) { $href = $linkNode->item(0)->nodeValue; if (preg_match('/regNumber=([^&]+)/', $href, $matches)) { $tender['regNumber'] = $matches[1]; } } // Используем tenderId как основной идентификатор if (empty($tender['regNumber']) && !empty($tender['tenderId'])) { $tender['regNumber'] = $tender['tenderId']; } $tenders[] = $tender; } // Пагинация $totalItems = 0; $paginationNode = $xpath->query("//div[contains(@class, 'paginator-block')]//span"); if ($paginationNode->length) { $text = $paginationNode->item(0)->textContent; if (preg_match('/из (\d+)/', $text, $matches)) { $totalItems = (int)$matches[1]; } } return [ 'content' => $tenders, 'totalElements' => $totalItems, 'regions' => $this->regionMapping ]; } // Получение деталей с кэшированием public function getTenderDetails($regNumber) { $cacheKey = "details_" . $regNumber; if (isset($this->cache[$cacheKey])) { return $this->cache[$cacheKey]; } $url = "https://zakupki.gov.ru/epz/order/notice/ea20/view/common-info.html?regNumber={$regNumber}"; $html = $this->fetch($url); $result = $this->parseTenderDetails($html, $regNumber); // Кэшируем детали на 10 минут $this->cache[$cacheKey] = $result; return $result; } // Полный парсинг всех деталей тендера private function parseTenderDetails($html, $regNumber) { $dom = new DOMDocument(); @$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); $xpath = new DOMXPath($dom); $details = [ 'regNumber' => $regNumber, 'generalInfo' => [], 'contactInfo' => [], 'procedureInfo' => [], 'priceInfo' => [], 'objectInfo' => [], 'requirements' => [], 'customerRequirements' => [], 'financialInfo' => [], 'applicationSecurity' => [], 'contractConditions' => [], 'contractSecurity' => [], 'bankingSupport' => [], 'documents' => [], 'lots' => [], 'region' => '', 'regionName' => '' ]; // 1. ОСНОВНАЯ ИНФОРМАЦИЯ ТЕНДЕРА $this->parseMainInfo($xpath, $details); // 2. ОБЩАЯ ИНФОРМАЦИЯ О ЗАКУПКЕ $this->parseGeneralInfo($xpath, $details); // 3. КОНТАКТНАЯ ИНФОРМАЦИЯ $this->parseContactInfo($xpath, $details); // 4. ИНФОРМАЦИЯ О ПРОЦЕДУРЕ ЗАКУПКИ $this->parseProcedureInfo($xpath, $details); // 5. НАЧАЛЬНАЯ ЦЕНА КОНТРАКТА $this->parsePriceInfo($xpath, $details); // 6. ИНФОРМАЦИЯ ОБ ОБЪЕКТЕ ЗАКУПКИ (КТРУ) $this->parseObjectInfo($xpath, $details); // 7. ПРЕИМУЩЕСТВА И ТРЕБОВАНИЯ $this->parseRequirements($xpath, $details); // 8. ТРЕБОВАНИЯ ЗАКАЗЧИКА $this->parseCustomerRequirements($xpath, $details); // 9. ФИНАНСОВАЯ ИНФОРМАЦИЯ $this->parseFinancialInfo($xpath, $details); // 10. ОБЕСПЕЧЕНИЕ ЗАЯВКИ $this->parseApplicationSecurity($xpath, $details); // 11. УСЛОВИЯ КОНТРАКТА $this->parseContractConditions($xpath, $details); // 12. ОБЕСПЕЧЕНИЕ ИСПОЛНЕНИЯ КОНТРАКТА $this->parseContractSecurity($xpath, $details); // 13. БАНКОВСКОЕ СОПРОВОЖДЕНИЕ $this->parseBankingSupport($xpath, $details); // 14. ДОКУМЕНТЫ $this->parseDocuments($xpath, $details); return $details; } // Парсинг основной информации тендера private function parseMainInfo($xpath, &$details) { // Извлекаем регион из блока time-zone $this->extractRegionFromTimeZone($xpath, $details); // Заголовок и номер $titleNode = $xpath->query("//div[contains(@class, 'cardMainInfo__title')]"); $details['generalInfo']['title'] = $titleNode->length ? trim($titleNode->item(0)->textContent) : ''; $numberNode = $xpath->query("//span[contains(@class, 'cardMainInfo__purchaseLink')]/a"); $details['generalInfo']['number'] = $numberNode->length ? trim($numberNode->item(0)->textContent) : ''; // Статус $statusNode = $xpath->query("//span[contains(@class, 'cardMainInfo__state')]"); $details['generalInfo']['status'] = $statusNode->length ? trim($statusNode->item(0)->textContent) : ''; // Объект закупки $objectNode = $xpath->query("//div[contains(@class, 'cardMainInfo__section')]/span[contains(text(), 'Объект закупки')]/following-sibling::span"); if (!$objectNode->length) { // Альтернативный поиск в заголовке $objectNode = $xpath->query("//h1[contains(@class, 'cardMainInfo__title')] | //div[contains(@class, 'cardMainInfo__title')]"); } $details['generalInfo']['object'] = $objectNode->length ? trim($objectNode->item(0)->textContent) : 'Не указан'; // Организация $orgNode = $xpath->query("//div[contains(@class, 'cardMainInfo__section')]/span[contains(text(), 'Организация') or contains(text(), 'размещение')]/following-sibling::span/a"); if (!$orgNode->length) { // Альтернативный поиск организации $orgNode = $xpath->query("//a[contains(@href, 'organization/view')]"); } $details['generalInfo']['organization'] = $orgNode->length ? trim($orgNode->item(0)->textContent) : 'Не указана'; // Цена $priceNode = $xpath->query("//span[contains(@class, 'cost')]"); $details['generalInfo']['price'] = $priceNode->length ? trim($priceNode->item(0)->textContent) : ''; // Даты из основной карточки $publishDateNode = $xpath->query("//div[contains(@class, 'cardMainInfo__section')]//span[contains(@class, 'cardMainInfo__title') and contains(text(), 'Размещено')]/following-sibling::span[contains(@class, 'cardMainInfo__content')]"); if ($publishDateNode->length) { $details['generalInfo']['publishDate'] = trim($publishDateNode->item(0)->textContent); } $updateDateNode = $xpath->query("//div[contains(@class, 'cardMainInfo__section')]//span[contains(@class, 'cardMainInfo__title') and contains(text(), 'Обновлено')]/following-sibling::span[contains(@class, 'cardMainInfo__content')]"); if ($updateDateNode->length) { $details['generalInfo']['updateDate'] = trim($updateDateNode->item(0)->textContent); } $endDateNode = $xpath->query("//div[contains(@class, 'cardMainInfo__section')]//span[contains(@class, 'cardMainInfo__title') and contains(text(), 'Окончание')]/following-sibling::span[contains(@class, 'cardMainInfo__content')]"); if ($endDateNode->length) { $details['generalInfo']['endDate'] = trim($endDateNode->item(0)->textContent); } // Если даты не найдены в основной карточке, ищем в других местах if (empty($details['generalInfo']['publishDate'])) { $altPublishNode = $xpath->query("//span[contains(text(), 'Размещено')]/following-sibling::span | //td[contains(text(), 'Размещено')]/following-sibling::td"); if ($altPublishNode->length) { $details['generalInfo']['publishDate'] = trim($altPublishNode->item(0)->textContent); } } if (empty($details['generalInfo']['updateDate'])) { $altUpdateNode = $xpath->query("//span[contains(text(), 'Обновлено')]/following-sibling::span | //td[contains(text(), 'Обновлено')]/following-sibling::td"); if ($altUpdateNode->length) { $details['generalInfo']['updateDate'] = trim($altUpdateNode->item(0)->textContent); } } if (empty($details['generalInfo']['endDate'])) { $altEndNode = $xpath->query("//span[contains(text(), 'Окончание')]/following-sibling::span | //td[contains(text(), 'Окончание')]/following-sibling::td"); if ($altEndNode->length) { $details['generalInfo']['endDate'] = trim($altEndNode->item(0)->textContent); } } // Добавляем информацию о часовом поясе $timeZoneNode = $xpath->query("//div[contains(@class, 'time-zone__value')]/span"); if ($timeZoneNode->length) { $details['generalInfo']['timeZone'] = trim($timeZoneNode->item(0)->textContent); } } // Парсинг общей информации о закупке private function parseGeneralInfo($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Общая информация о закупке')]/following-sibling::section | //h2[contains(text(), 'Общая информация о закупке')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['generalInfo'][$this->normalizeKey($title)] = $info; } } } // Парсинг контактной информации private function parseContactInfo($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Контактная информация')]/following-sibling::section | //h2[contains(text(), 'Контактная информация')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['contactInfo'][$this->normalizeKey($title)] = $info; // Определение региона из адреса, только если он еще не определен if (empty($details['region']) && (stripos($title, 'адрес') !== false || stripos($title, 'нахождение') !== false)) { foreach ($this->regionMapping as $code => $name) { if (stripos($info, $name) !== false) { $details['region'] = $code; $details['regionName'] = $name; break; } } } } } } // Парсинг информации о процедуре закупки private function parseProcedureInfo($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Информация о процедуре закупки')]/following-sibling::section | //h2[contains(text(), 'Информация о процедуре закупки')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['procedureInfo'][$this->normalizeKey($title)] = $info; } } } // Парсинг информации о цене private function parsePriceInfo($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Начальная') and contains(text(), 'цена')]/following-sibling::section | //h2[contains(text(), 'Начальная') and contains(text(), 'цена')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['priceInfo'][$this->normalizeKey($title)] = $info; } } } // Парсинг информации об объекте закупки (КТРУ) private function parseObjectInfo($xpath, &$details) { $table = $xpath->query("//table[contains(@class, 'tableBlock')]//tbody[contains(@class, 'tableBlock__body')]"); if ($table->length) { $rows = $xpath->query(".//tr[contains(@class, 'tableBlock__row')]", $table->item(0)); foreach ($rows as $row) { $cols = $xpath->query(".//td[contains(@class, 'tableBlock__col')]", $row); if ($cols->length >= 6) { $item = [ 'code' => trim($cols->item(1)->textContent), 'name' => trim($cols->item(2)->textContent), 'unit' => $cols->length > 3 ? trim($cols->item(3)->textContent) : '', 'quantity' => $cols->length > 4 ? trim($cols->item(4)->textContent) : '', 'price' => $cols->length > 5 ? trim($cols->item(5)->textContent) : '', 'sum' => $cols->length > 6 ? trim($cols->item(6)->textContent) : '' ]; // Извлечение характеристик $characteristics = []; $charRows = $xpath->query(".//tr[contains(@style, 'display: none')]//table//tr", $row->parentNode); foreach ($charRows as $charRow) { $charCols = $xpath->query(".//td", $charRow); if ($charCols->length >= 2) { $charName = trim($charCols->item(0)->textContent); $charValue = trim($charCols->item(1)->textContent); if (!empty($charName) && !empty($charValue)) { $characteristics[$charName] = $charValue; } } } $item['characteristics'] = $characteristics; $details['objectInfo'][] = $item; } } } // Итоговая сумма $totalNode = $xpath->query("//tfoot//span[contains(@class, 'cost')]"); if ($totalNode->length) { $details['objectInfo']['total'] = trim($totalNode->item(0)->textContent); } } // Парсинг требований и преимуществ private function parseRequirements($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Преимущества') or contains(text(), 'требования')]/following-sibling::section | //h2[contains(text(), 'Преимущества') or contains(text(), 'требования')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['requirements'][$this->normalizeKey($title)] = $info; } } } // Парсинг требований заказчика private function parseCustomerRequirements($xpath, &$details) { $sections = $xpath->query("//span[contains(text(), 'Требования заказчика')]/ancestor::div[contains(@class, 'collapse__title')]/following-sibling::div//section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['customerRequirements'][$this->normalizeKey($title)] = $info; } } } // Парсинг финансовой информации private function parseFinancialInfo($xpath, &$details) { // Финансовое обеспечение $tables = $xpath->query("//h2[contains(text(), 'финансирования') or contains(text(), 'Финансовое обеспечение')]/following-sibling::table | //h2[contains(text(), 'финансирования') or contains(text(), 'Финансовое обеспечение')]/parent::*/following-sibling::*/table"); foreach ($tables as $table) { $rows = $xpath->query(".//tr", $table); $tableData = []; foreach ($rows as $row) { $cols = $xpath->query(".//td | .//th", $row); $rowData = []; foreach ($cols as $col) { $rowData[] = trim($col->textContent); } if (!empty($rowData)) { $tableData[] = $rowData; } } $details['financialInfo']['tables'][] = $tableData; } // Дополнительные секции $sections = $xpath->query("//h2[contains(text(), 'финансирования')]/following-sibling::section | //h2[contains(text(), 'финансирования')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['financialInfo'][$this->normalizeKey($title)] = $info; } } } // Парсинг обеспечения заявки private function parseApplicationSecurity($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Обеспечение заявки')]/following-sibling::section | //h2[contains(text(), 'Обеспечение заявки')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['applicationSecurity'][$this->normalizeKey($title)] = $info; } } } // Парсинг условий контракта private function parseContractConditions($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Условия контракта')]/following-sibling::section | //h2[contains(text(), 'Условия контракта')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['contractConditions'][$this->normalizeKey($title)] = $info; } } } // Парсинг обеспечения исполнения контракта private function parseContractSecurity($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'Обеспечение исполнения контракта')]/following-sibling::section | //h2[contains(text(), 'Обеспечение исполнения контракта')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['contractSecurity'][$this->normalizeKey($title)] = $info; } } } // Парсинг банковского сопровождения private function parseBankingSupport($xpath, &$details) { $sections = $xpath->query("//h2[contains(text(), 'банковском') or contains(text(), 'казначейском')]/following-sibling::section | //h2[contains(text(), 'банковском') or contains(text(), 'казначейском')]/parent::*/following-sibling::*/section"); foreach ($sections as $section) { $titleNode = $xpath->query(".//span[contains(@class, 'section__title')]", $section); $infoNode = $xpath->query(".//span[contains(@class, 'section__info')]", $section); if ($titleNode->length && $infoNode->length) { $title = trim($titleNode->item(0)->textContent); $info = trim($infoNode->item(0)->textContent); $details['bankingSupport'][$this->normalizeKey($title)] = $info; } } } // Парсинг документов private function parseDocuments($xpath, &$details) { $docNodes = $xpath->query("//a[contains(@class, 'section__doc-link')] | //a[contains(@href, '/document/')]"); foreach ($docNodes as $node) { $docHref = $node->getAttribute('href'); if (!preg_match('/^https?:\/\//', $docHref)) { $docHref = 'https://zakupki.gov.ru' . $docHref; } $details['documents'][] = [ 'fileName' => trim($node->textContent), 'url' => $docHref ]; } } // Извлечение региона из блока time-zone private function extractRegionFromTimeZone($xpath, &$details) { $timeZoneNode = $xpath->query("//div[contains(@class, 'time-zone__value')]/span"); if ($timeZoneNode->length) { $timeZoneText = trim($timeZoneNode->item(0)->textContent); // Извлекаем название региона из строки типа "Москва МСК (UTC+3)" if (preg_match('/^([^М\s]+)/', $timeZoneText, $matches)) { $regionName = mb_strtolower(trim($matches[1]), 'UTF-8'); // Ищем соответствие в нашем маппинге регионов foreach ($this->regionMapping as $code => $name) { if (stripos($regionName, mb_strtolower($name, 'UTF-8')) !== false || stripos(mb_strtolower($name, 'UTF-8'), $regionName) !== false) { $details['region'] = $code; $details['regionName'] = $name; return true; } } // Ищем в городах foreach ($this->cityMapping as $city => $code) { if (stripos($regionName, $city) !== false) { $details['region'] = $code; $details['regionName'] = $this->regionMapping[$code]; return true; } } // Если не нашли в маппинге, но регион есть, сохраняем его название if (!empty($regionName)) { $details['regionName'] = ucfirst($regionName); return true; } } } return false; } // Нормализация ключей для массивов private function normalizeKey($key) { $key = trim($key); $key = preg_replace('/[^\w\s-]/u', '', $key); $key = preg_replace('/\s+/', '_', $key); $key = mb_strtolower($key, 'UTF-8'); return $key; } // Получение списка доступных регионов public function getRegions() { return $this->regionMapping; } public function __destruct() { if ($this->curl) { curl_close($this->curl); } if (file_exists($this->cookies)) { @unlink($this->cookies); } } } // Обработка запросов if (isset($_GET['action'])) { header('Content-Type: application/json; charset=utf-8'); try { $parser = new ZakupkiParser(); if ($_GET['action'] === 'search') { $params = [ 'page' => $_GET['page'] ?? 1, 'size' => $_GET['per_page'] ?? 20, 'search_text' => $_GET['search_text'] ?? '', 'inn' => $_GET['inn'] ?? '', 'price_min' => $_GET['price_min'] ?? null, 'price_max' => $_GET['price_max'] ?? null, 'date_from' => $_GET['date_from'] ?? null, 'date_to' => $_GET['date_to'] ?? null, 'regions' => isset($_GET['regions']) ? explode(',', $_GET['regions']) : [], 'city_search' => $_GET['city_search'] ?? '' ]; $result = $parser->searchTenders($params); echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } elseif ($_GET['action'] === 'detail' && !empty($_GET['regNumber'])) { $details = $parser->getTenderDetails($_GET['regNumber']); echo json_encode($details, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } elseif ($_GET['action'] === 'regions') { $regions = $parser->getRegions(); echo json_encode($regions, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); } } catch (Exception $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()], JSON_UNESCAPED_UNICODE); } exit; } ?> <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Полный парсер госзакупок</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <style> .card-detail { transition: all 0.3s; border-left: 4px solid transparent; } .card-detail:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); border-left-color: #0d6efd; } .section-title { border-left: 4px solid #0d6efd; padding-left: 15px; margin: 25px 0 15px; } .loader { width: 3rem; height: 3rem; } .document-badge { cursor: pointer; transition: all 0.2s; margin: 2px; } .document-badge:hover { background: #0d6efd!important; transform: scale(1.05); } .pagination .page-item.active .page-link { background: #0d6efd; border-color: #0d6efd; } .lot-badge { font-size: 0.85rem; } .region-badge { font-size: 0.75rem; margin-left: 5px; } .select2-container { width: 100% !important; } .tender-stats { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px; padding: 20px; margin-bottom: 20px; } .cache-info { position: fixed; top: 10px; right: 10px; z-index: 1000; } .detail-section { margin-bottom: 30px; border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden; } .detail-section-header { background: #f8f9fa; padding: 15px 20px; border-bottom: 1px solid #e9ecef; font-weight: 600; color: #495057; } .detail-section-content { padding: 20px; } .info-table { width: 100%; margin-bottom: 0; } .info-table td { padding: 8px 12px; border-bottom: 1px solid #f1f3f4; } .info-table td:first-child { font-weight: 500; color: #6c757d; width: 30%; } .object-item { border: 1px solid #e9ecef; border-radius: 6px; margin-bottom: 15px; overflow: hidden; } .object-item-header { background: #f8f9fa; padding: 10px 15px; font-weight: 500; } .object-item-content { padding: 15px; } .characteristics-table { font-size: 0.9em; margin-top: 10px; } .financial-table { font-size: 0.9em; margin-bottom: 20px; } </style> </head> <body> <div class="container py-4"> <h1 class="text-center mb-4"> <i class="fas fa-file-contract me-2"></i>Полный парсер госзакупок </h1> <!-- Информация о кэше --> <div id="cacheInfo" class="cache-info d-none"> <div class="alert alert-info alert-dismissible fade show" role="alert"> <i class="fas fa-info-circle me-2"></i> <span id="cacheMessage">Данные загружены из кэша</span> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> </div> <!-- Статистика --> <div id="tenderStats" class="tender-stats d-none"> <div class="row text-center"> <div class="col-md-3"> <h3 id="totalTenders">0</h3> <p class="mb-0">Всего тендеров</p> </div> <div class="col-md-3"> <h3 id="totalValue">0 ₽</h3> <p class="mb-0">Общая стоимость</p> </div> <div class="col-md-3"> <h3 id="avgValue">0 ₽</h3> <p class="mb-0">Средняя стоимость</p> </div> <div class="col-md-3"> <h3 id="regionsCount">0</h3> <p class="mb-0">Регионов</p> </div> </div> </div> <!-- Форма поиска --> <div class="card mb-4"> <div class="card-body"> <form id="searchForm" class="row g-3"> <div class="col-md-6"> <label class="form-label">Ключевые слова</label> <input type="text" name="search_text" class="form-control" placeholder="Номер или название закупки..."> </div> <div class="col-md-6"> <label class="form-label">ИНН заказчика</label> <input type="text" name="inn" class="form-control" placeholder="ИНН организации..."> </div> <div class="col-md-6"> <label class="form-label">Регионы</label> <select name="regions" id="regionSelect" class="form-select" multiple> <!-- Опции будут загружены динамически --> </select> <div class="form-text">Выберите один или несколько регионов для фильтрации</div> </div> <div class="col-md-6"> <label class="form-label">Поиск по городу/региону</label> <input type="text" name="city_search" class="form-control" placeholder="Введите название города или региона..."> <div class="form-text">Например: Москва, Санкт-Петербург, Екатеринбург</div> </div> <div class="col-md-3"> <label class="form-label">Минимальная цена</label> <div class="input-group"> <input type="number" name="price_min" class="form-control" placeholder="₽"> <span class="input-group-text">₽</span> </div> </div> <div class="col-md-3"> <label class="form-label">Максимальная цена</label> <div class="input-group"> <input type="number" name="price_max" class="form-control" placeholder="₽"> <span class="input-group-text">₽</span> </div> </div> <div class="col-md-3"> <label class="form-label">Дата от</label> <input type="date" name="date_from" class="form-control"> </div> <div class="col-md-3"> <label class="form-label">Дата до</label> <input type="date" name="date_to" class="form-control"> </div> <div class="col-md-2"> <label class="form-label">На странице</label> <select name="per_page" class="form-select"> <option value="10">10</option> <option value="20" selected>20</option> <option value="50">50</option> <option value="100">100</option> </select> </div> <div class="col-md-8 d-flex align-items-end"> <button type="submit" class="btn btn-primary w-100"> <i class="fas fa-search me-2"></i>Найти тендеры </button> </div> <div class="col-md-2 d-flex align-items-end"> <button type="button" class="btn btn-outline-secondary w-100" onclick="app.clearCache()"> <i class="fas fa-trash me-2"></i>Очистить кэш </button> </div> </form> </div> </div> <!-- Результаты --> <div id="results" class="mb-4"> <div class="text-center py-5"> <div class="spinner-border text-primary loader" role="status"> <span class="visually-hidden">Загрузка...</span> </div> <p class="mt-3">Загружаем список тендеров...</p> </div> </div> <!-- Пагинация --> <nav id="pagination" class="d-none"> <ul class="pagination justify-content-center"> <!-- Номера страниц будут вставлены здесь --> </ul> </nav> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script> <script> class ZakupkiApp { constructor() { this.currentPage = 1; this.totalPages = 1; this.perPage = 20; this.totalItems = 0; this.currentTender = null; this.cache = new Map(); this.regions = {}; this.initializeRegions(); this.searchTenders(); } async initializeRegions() { try { const response = await fetch('?action=regions'); if (response.ok) { this.regions = await response.json(); this.populateRegionSelect(); } } catch (error) { console.error('Ошибка загрузки регионов:', error); } } populateRegionSelect() { const select = document.getElementById('regionSelect'); select.innerHTML = ''; Object.entries(this.regions).forEach(([code, name]) => { const option = document.createElement('option'); option.value = code; option.textContent = name; select.appendChild(option); }); // Инициализация Select2 $('#regionSelect').select2({ placeholder: 'Выберите регионы...', allowClear: true, width: '100%' }); } async searchTenders(page = 1) { try { this.showLoader('Загружаем список тендеров...'); this.currentPage = page; const formData = new FormData(document.getElementById('searchForm')); const selectedRegions = $('#regionSelect').val() || []; const params = { action: 'search', page: page, per_page: formData.get('per_page') || 20, search_text: formData.get('search_text') || '', inn: formData.get('inn') || '', price_min: formData.get('price_min') || null, price_max: formData.get('price_max') || null, date_from: formData.get('date_from') || null, date_to: formData.get('date_to') || null, regions: selectedRegions.join(','), city_search: formData.get('city_search') || '' }; // Проверяем кэш const cacheKey = JSON.stringify(params); if (this.cache.has(cacheKey)) { const cachedResult = this.cache.get(cacheKey); this.renderTenders(cachedResult); this.showCacheInfo('Данные загружены из кэша'); return; } // Формируем параметры запроса const queryString = Object.keys(params) .filter(key => params[key] !== null && params[key] !== '') .map(key => `${key}=${encodeURIComponent(params[key])}`) .join('&'); const response = await fetch(`?${queryString}`); if (!response.ok) throw new Error('Ошибка сети'); const result = await response.json(); // Сохраняем в кэш this.cache.set(cacheKey, result); this.renderTenders(result); } catch (error) { this.showError(error.message); } } renderTenders(data) { const tenders = data.content || []; this.totalItems = data.totalElements || tenders.length; this.totalPages = Math.ceil(this.totalItems / this.perPage); // Обновляем статистику this.updateStats(tenders); let html = `<h2 class="mb-3">Найдено тендеров: ${this.totalItems.toLocaleString('ru-RU')}</h2>`; if (tenders.length === 0) { html += `<div class="alert alert-warning"> <i class="fas fa-exclamation-triangle me-2"></i> По вашему запросу тендеров не найдено </div>`; } else { html += '<div class="row g-4">'; tenders.forEach(tender => { const regNumber = tender.regNumber || tender.tenderId || ''; const number = tender.purchaseNumber || ''; const title = tender.purchaseObjectInfo || 'Без названия'; const customer = tender.customer?.fullName || 'Заказчик не указан'; // Цена let price = 'Цена не указана'; if (tender.lot?.price) { const numPrice = parseFloat(tender.lot.price.replace(/[^\d.]/g, '')); if (!isNaN(numPrice)) { price = numPrice.toLocaleString('ru-RU', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' ₽'; } } // Регион const regionBadge = tender.region && this.regions[tender.region] ? `<span class="badge bg-secondary region-badge">${this.regions[tender.region]}</span>` : ''; // Даты const formatDate = (dateString) => { if (!dateString) return 'Н/Д'; try { const date = new Date(dateString); return isNaN(date) ? dateString : date.toLocaleDateString('ru-RU'); } catch { return dateString; } }; const posted = formatDate(tender.publishDate); const updated = formatDate(tender.updateDate); const deadline = formatDate(tender.submissionCloseDateTime); html += ` <div class="col-md-6"> <div class="card card-detail h-100" data-tender-id="${regNumber}"> <div class="card-body"> <h5 class="card-title text-primary">${title}${regionBadge}</h5> <h6 class="card-subtitle mb-2 text-muted">${number}</h6> <div class="mb-2"> <span class="badge bg-info">${price}</span> </div> <p class="card-text"> <strong>Заказчик:</strong> ${customer}<br> <strong>Размещено:</strong> ${posted}<br> <strong>Обновлено:</strong> ${updated}<br> <strong>Окончание подачи:</strong> ${deadline} </p> <button class="btn btn-sm btn-outline-primary" onclick="app.showTenderDetails('${regNumber}')"> <i class="fas fa-info-circle me-1"></i> Подробнее </button> </div> </div> </div>`; }); html += '</div>'; } document.getElementById('results').innerHTML = html; this.renderPagination(); } updateStats(tenders) { const statsContainer = document.getElementById('tenderStats'); if (tenders.length === 0) { statsContainer.classList.add('d-none'); return; } let totalValue = 0; const regions = new Set(); tenders.forEach(tender => { if (tender.lot?.price) { const price = parseFloat(tender.lot.price.replace(/[^\d.]/g, '')); if (!isNaN(price)) { totalValue += price; } } // Учитываем регион, если он определен if (tender.region && tender.region !== '') { regions.add(tender.region); } // Также проверяем regionName для случаев, когда код региона не определен if (!tender.region && tender.regionName && tender.regionName !== 'Не определен') { regions.add(tender.regionName); } }); const avgValue = tenders.length > 0 ? totalValue / tenders.length : 0; document.getElementById('totalTenders').textContent = this.totalItems.toLocaleString('ru-RU'); document.getElementById('totalValue').textContent = totalValue.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 }) + ' ₽'; document.getElementById('avgValue').textContent = avgValue.toLocaleString('ru-RU', { minimumFractionDigits: 0, maximumFractionDigits: 0 }) + ' ₽'; document.getElementById('regionsCount').textContent = regions.size; statsContainer.classList.remove('d-none'); } showCacheInfo(message) { const cacheInfo = document.getElementById('cacheInfo'); const cacheMessage = document.getElementById('cacheMessage'); cacheMessage.textContent = message; cacheInfo.classList.remove('d-none'); setTimeout(() => { cacheInfo.classList.add('d-none'); }, 3000); } clearCache() { this.cache.clear(); this.showCacheInfo('Кэш очищен'); } renderPagination() { const paginationContainer = document.querySelector('#pagination ul'); paginationContainer.innerHTML = ''; if (this.totalPages <= 1) { document.getElementById('pagination').classList.add('d-none'); return; } document.getElementById('pagination').classList.remove('d-none'); // Кнопка "Назад" const prevBtn = document.createElement('li'); prevBtn.className = `page-item ${this.currentPage === 1 ? 'disabled' : ''}`; prevBtn.innerHTML = `<a class="page-link" href="#" onclick="app.goToPage(${this.currentPage - 1})">&laquo;</a>`; paginationContainer.appendChild(prevBtn); // Номера страниц const startPage = Math.max(1, this.currentPage - 2); const endPage = Math.min(this.totalPages, startPage + 4); for (let i = startPage; i <= endPage; i++) { const pageItem = document.createElement('li'); pageItem.className = `page-item ${i === this.currentPage ? 'active' : ''}`; pageItem.innerHTML = `<a class="page-link" href="#" onclick="app.goToPage(${i})">${i}</a>`; paginationContainer.appendChild(pageItem); } // Кнопка "Вперед" const nextBtn = document.createElement('li'); nextBtn.className = `page-item ${this.currentPage === this.totalPages ? 'disabled' : ''}`; nextBtn.innerHTML = `<a class="page-link" href="#" onclick="app.goToPage(${this.currentPage + 1})">&raquo;</a>`; paginationContainer.appendChild(nextBtn); } goToPage(page) { if (page < 1) page = 1; if (page > this.totalPages) page = this.totalPages; this.searchTenders(page); } async showTenderDetails(identifier) { try { this.showLoader('Загружаем детали тендера...'); this.currentTender = identifier; // Проверяем кэш const cacheKey = `details_${identifier}`; if (this.cache.has(cacheKey)) { const cachedDetails = this.cache.get(cacheKey); this.renderTenderDetails(cachedDetails); this.showCacheInfo('Детали загружены из кэша'); return; } const response = await fetch(`?action=detail&regNumber=${encodeURIComponent(identifier)}`); if (!response.ok) throw new Error('Ошибка загрузки деталей'); const details = await response.json(); // Сохраняем в кэш this.cache.set(cacheKey, details); this.renderTenderDetails(details); } catch (error) { this.showError(error.message); } } renderTenderDetails(details) { if (!details) { this.showError('Не удалось загрузить детали тендера'); return; } const regionInfo = details.region && this.regions[details.region] ? `<span class="badge bg-info">${this.regions[details.region]}</span>` : ''; let html = ` <div class="mb-4"> <button class="btn btn-secondary" onclick="app.backToList()"> <i class="fas fa-arrow-left me-2"></i>Назад к списку </button> </div> <!-- Основная информация --> <div class="detail-section"> <div class="detail-section-header"> <h4 class="mb-0"> <i class="fas fa-info-circle me-2"></i> ${details.generalInfo?.object || 'Детальная информация о тендере'} ${regionInfo} </h4> </div> <div class="detail-section-content"> <table class="info-table"> <tr><td>Регистрационный номер</td><td>${details.regNumber || 'Не указан'}</td></tr> <tr><td>Номер закупки</td><td>${details.generalInfo?.number || 'Не указан'}</td></tr> <tr><td>Статус</td><td><span class="badge bg-info">${details.generalInfo?.status || 'Неизвестен'}</span></td></tr> <tr><td>Организация</td><td>${details.generalInfo?.organization || 'Не указана'}</td></tr> <tr><td>Начальная цена</td><td>${details.generalInfo?.price || 'Не указана'}</td></tr> <tr><td>Дата размещения</td><td>${details.generalInfo?.publishDate || 'Не указана'}</td></tr> <tr><td>Дата обновления</td><td>${details.generalInfo?.updateDate || 'Не указана'}</td></tr> <tr><td>Окончание подачи заявок</td><td>${details.generalInfo?.endDate || 'Не указана'}</td></tr> <tr><td>Регион</td><td>${details.regionName || 'Не определен'}</td></tr> </table> </div> </div>`; // Общая информация о закупке if (details.generalInfo && Object.keys(details.generalInfo).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-clipboard-list me-2"></i>Общая информация о закупке </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.generalInfo).forEach(([key, value]) => { if (value && !['title', 'number', 'status', 'object', 'organization', 'price', 'publishDate', 'updateDate', 'endDate'].includes(key)) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Контактная информация if (details.contactInfo && Object.keys(details.contactInfo).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-address-book me-2"></i>Контактная информация </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.contactInfo).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Информация о процедуре закупки if (details.procedureInfo && Object.keys(details.procedureInfo).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-calendar-alt me-2"></i>Информация о процедуре закупки </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.procedureInfo).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Информация о цене if (details.priceInfo && Object.keys(details.priceInfo).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-ruble-sign me-2"></i>Информация о цене контракта </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.priceInfo).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Информация об объекте закупки (КТРУ) if (details.objectInfo && Array.isArray(details.objectInfo) && details.objectInfo.length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-boxes me-2"></i>Информация об объекте закупки (КТРУ) </div> <div class="detail-section-content">`; details.objectInfo.forEach((item, index) => { if (typeof item === 'object' && item.code) { html += ` <div class="object-item"> <div class="object-item-header"> <strong>Позиция ${index + 1}:</strong> ${item.code} - ${item.name} </div> <div class="object-item-content"> <div class="row"> <div class="col-md-6"> <table class="info-table"> <tr><td>Код КТРУ</td><td>${item.code}</td></tr> <tr><td>Наименование</td><td>${item.name}</td></tr> <tr><td>Единица измерения</td><td>${item.unit}</td></tr> </table> </div> <div class="col-md-6"> <table class="info-table"> <tr><td>Количество</td><td>${item.quantity}</td></tr> <tr><td>Цена за единицу</td><td>${item.price}</td></tr> <tr><td>Общая стоимость</td><td>${item.sum}</td></tr> </table> </div> </div>`; // Характеристики if (item.characteristics && Object.keys(item.characteristics).length > 0) { html += ` <h6 class="mt-3 mb-2">Характеристики:</h6> <table class="characteristics-table table table-sm"> <thead> <tr> <th>Характеристика</th> <th>Значение</th> </tr> </thead> <tbody>`; Object.entries(item.characteristics).forEach(([charName, charValue]) => { html += `<tr><td>${charName}</td><td>${charValue}</td></tr>`; }); html += `</tbody></table>`; } html += `</div></div>`; } }); if (details.objectInfo.total) { html += `<div class="alert alert-info mt-3"> <strong>Итого:</strong> ${details.objectInfo.total} </div>`; } html += `</div></div>`; } // Требования и преимущества if (details.requirements && Object.keys(details.requirements).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-check-circle me-2"></i>Преимущества и требования к участникам </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.requirements).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Требования заказчика if (details.customerRequirements && Object.keys(details.customerRequirements).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-user-tie me-2"></i>Требования заказчика </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.customerRequirements).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Финансовая информация if (details.financialInfo && Object.keys(details.financialInfo).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-chart-line me-2"></i>Финансовая информация </div> <div class="detail-section-content">`; // Таблицы финансирования if (details.financialInfo.tables && Array.isArray(details.financialInfo.tables)) { details.financialInfo.tables.forEach((table, index) => { if (Array.isArray(table) && table.length > 0) { html += `<table class="financial-table table table-striped">`; table.forEach((row, rowIndex) => { if (Array.isArray(row)) { html += `<tr>`; row.forEach(cell => { const tag = rowIndex === 0 ? 'th' : 'td'; html += `<${tag}>${cell}</${tag}>`; }); html += `</tr>`; } }); html += `</table>`; } }); } // Дополнительная финансовая информация html += `<table class="info-table">`; Object.entries(details.financialInfo).forEach(([key, value]) => { if (value && key !== 'tables') { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Обеспечение заявки if (details.applicationSecurity && Object.keys(details.applicationSecurity).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-shield-alt me-2"></i>Обеспечение заявки </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.applicationSecurity).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Условия контракта if (details.contractConditions && Object.keys(details.contractConditions).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-file-contract me-2"></i>Условия контракта </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.contractConditions).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Обеспечение исполнения контракта if (details.contractSecurity && Object.keys(details.contractSecurity).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-lock me-2"></i>Обеспечение исполнения контракта </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.contractSecurity).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Банковское сопровождение if (details.bankingSupport && Object.keys(details.bankingSupport).length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-university me-2"></i>Банковское и казначейское сопровождение </div> <div class="detail-section-content"> <table class="info-table">`; Object.entries(details.bankingSupport).forEach(([key, value]) => { if (value) { const label = this.formatLabel(key); html += `<tr><td>${label}</td><td>${value}</td></tr>`; } }); html += `</table></div></div>`; } // Документы if (details.documents && details.documents.length > 0) { html += ` <div class="detail-section"> <div class="detail-section-header"> <i class="fas fa-file-pdf me-2"></i>Документы </div> <div class="detail-section-content"> <div class="d-flex flex-wrap gap-2">`; details.documents.forEach(doc => { html += `<a href="${doc.url}" target="_blank" class="document-badge badge bg-success text-decoration-none"> <i class="fas fa-file-pdf me-1"></i> ${doc.fileName || 'Документ'} </a>`; }); html += `</div></div></div>`; } document.getElementById('results').innerHTML = html; document.getElementById('pagination').classList.add('d-none'); } formatLabel(key) { return key.replace(/_/g, ' ') .replace(/\b\w/g, l => l.toUpperCase()) .replace(/([a-z])([A-Z])/g, '$1 $2'); } backToList() { this.searchTenders(this.currentPage); } showLoader(message = 'Загрузка данных...') { document.getElementById('results').innerHTML = ` <div class="text-center py-5"> <div class="spinner-border text-primary loader" role="status"> <span class="visually-hidden">Загрузка...</span> </div> <p class="mt-3">${message}</p> </div>`; document.getElementById('pagination').classList.add('d-none'); } showError(message) { document.getElementById('results').innerHTML = ` <div class="alert alert-danger"> <h4><i class="fas fa-exclamation-circle me-2"></i> Ошибка</h4> <p>${message}</p> <button class="btn btn-secondary" onclick="app.searchTenders()"> <i class="fas fa-sync me-1"></i> Попробовать снова </button> </div>`; document.getElementById('pagination').classList.add('d-none'); } } // Инициализация приложения const app = new ZakupkiApp(); // Обработка формы document.getElementById('searchForm').addEventListener('submit', function(e) { e.preventDefault(); app.searchTenders(); }); </script> </body> </html>

госзакупкиPHPпарсер12.06.2025

React Firebase админ-панель

Web Developmentru
4.0

Мне нужна админ-панель для моего сайта на react. Используй авторизацию через firebase

ReactFirebaseадмин-панель03.04.2025

Олтин койда ҳисобловчи

Математикаru
4.0

import math def calculate_golden_ratios(x): """Фойдаланувчи киритган рақам асосида Олтин койда ва унинг тескарисини ҳисоблаш""" phi = (1 + math.sqrt(5)) / 2 golden_multiplied = x * phi # x * φ golden_divided = x / phi # x / φ return phi, golden_multiplied, golden_divided if __name__ == "__main__": print("🌟 Олтин койда ҳисобловчи 🌟") print("Фойдаланувчи рақамини киритинг (мисол: 5, 10.5, 100):") try: x = float(input(">>> ")) # Ҳар қандай рақам қабул қилинади phi, multiplied, divided = calculate_golden_ratios(x) print(f"\nОлтин койда (φ): {phi:.15f}") print(f"✅ {x} × φ = {multiplied:.15f}") print(f"✅ {x} ÷ φ = {divided:.15f}") except ValueError: print("❗ Хатолик: Рақам киритинг!")

Олтин койдаматематикаҳисоблаш29.03.2025

Создание хакерского приложения

Программированиеru
4.0

Сделай "хакерское" приложение с успокаивающей музыкой на фоне и терминалом с зеленым текстом, к терминалу будет подключена нейросеть deepseek через api, сделай что бы приложение можно было вызвать комбинацией клавиш windows+shift+f, а так же сделай что бы в терминале (именно в самом терминале) можно было воспроизводить видео из ютуба, сделай что бы в приложении можно было вводить текст не только текстом но и голосом. Сделай что бы по приложению была инструкция на английском и русском языках (в самом приложении) а еще что бы было 2 страницы - главная (с терминалом) и дополнительная с кнопками которые вызывают команды из обычного терминала но только по нажатию. Добавь в терминал команды для управления системой, всего команд должно быть 200+, еще на 2 страница справа сделай анимацию ноутбука на экране которого бесконечно взламывается система

хакерское приложениенейросетьтерминал29.03.2025

Умный хакер-помощник

Программное обеспечениеru
4.0

Создай умного хакера-помощника который будет разговаривать с пользователем как текстом так и голосом хакера. Основой помощника будет нейросеть deepseek с которой и будет общение и 50+ базовых команд работающих оффлайн. Сделай что бы справа была панель со страницами и чатом с "хакером" а так же что бы у хакера был аватар, эмоции и характер хакера. Сделай что бы у приложения было несколько обычных тем, несколько градиентных (голубо-розовая тема и сине-фиолетовая тема) и что бы были статичные и динамичные темы. Помощник будет помогать как в системе так и в браузере. Сделай что бы в помощнике был свой антивирус и adblock. А так же добавь в помощника развлекательную страницу с радио, анекдотами и играми, но и страницу с "приложением дня" и другими полезными приложениями по типу: антивирусы - drweb, kaspersky. игровые площадки - steam, epic games store. браузеры - mozilla firefox, chrome, и другие. Так же сделай что бы помощник открывался по нажатию сочетаний клавиш windows+shift+f, и что бы приложение закреплялось при установке в панели задач, на рабочем столе и в меню пуск. Так же сделай что бы приложение в установщике можно было дополнять всякими интересными функциями и плагинами.

хакернейросетьоффлайн команды29.03.2025

Умный хакер-помощник

Программное обеспечениеru
4.0

Создай умного хакера-помощника который будет разговаривать с пользователем как текстом так и голосом хакера. Основой помощника будет нейросеть deepseek и 50+ базовых команд работающих оффлайн. Сделай что бы справа была панель со страницами и чатом с "хакером" а так же что бы у хакера был аватар, эмоции и характер хакера. Сделай что бы у приложения было несколько обычных тем, несколько градиентных (голубо-розовая тема и сине-фиолетовая тема) и что бы были статичные и динамичные темы. Помощник будет помогать как в системе так и в браузере. Сделай что бы в помощнике был свой антивирус и adblock. А так же добавь в помощника развлекательную страницу с радио, анекдотами и играми, но и страницу с "приложением дня" и другими полезными приложениями по типу: антивирусы - drweb, kaspersky. игровые площадки - steam, epic games store. браузеры - mozilla firefox, chrome, и другие. Так же сделай что бы помощник открывался по нажатию сочетаний клавиш windows+shift+f, и что бы приложение закреплялось при установке в панели задач, на рабочем столе и в меню пуск. Так же сделай что бы приложение в установщике можно было дополнять всякими интересными функциями и плагинами, а так же что бы можно было выбрать дополнительного помощника - на экране входа в юзера виндовс.

нейросетьпомощникантивирус29.03.2025

передать форму в приложение

Программированиеru
4.0

передать содержимое формы в другое приложение

формаприложениепередача данных28.03.2025

отображать секции по ссылке

Информационные технологииru
4.0

отображать секции по ссылке

отображатьсекцииссылка28.03.2025

открыть новое окно

веб-разработкаru
4.0

открыть новое окно на странице

веб-разработкабраузерHTML28.03.2025

открыть новую страницу

веб-разработкаru
4.0

открыть новую страницу

новыйстраницаоткрыть28.03.2025

创建菜单页面与表单处理

网页开发ru
4.0

Создай страницы с пунктами меню index, work, history. На index странице создай форму my_form с checkbox, input, select, textarea сохрани заполненную форму my_form в файл базы данных sqlite.db. Создай страницу work и выведи на нее все заполненные данные в форме my_form из файла базы данных sqlite.db. Создай страницу history покажи на ней всю историю заполнений формы my_form

网页开发表单处理SQLite数据库28.03.2025

创建菜单页面与表单处理

网页开发ru
4.0

Создай страницы с пунктами меню index, work, history. На index странице создай форму my_form с checkbox, input, select, textarea сохрани заполненную форму my_form в файл базы данных sqlite.db. Создай страницу work и выведи на нее все заполненные данные в форме my_form из файла базы данных sqlite.db. Создай страницу history покажи на ней всю историю заполнений формы my_form

网页开发表单处理SQLite数据库28.03.2025

创建SQLite表单与历史页面

编程开发ru
4.0

создать 2 страницы. 1 первая страница главная с формой checkbox select input результат сохранить базу данных в sqlite. 2 Вторая станица История для просмотра сохранённых в базе данных заполненных форм

SQLite表单处理数据库管理28.03.2025
PreviousPage 1 of 2Next