22 - python & all web labs
94
labWeb/kt_3/booking.html
Normal file
@@ -0,0 +1,94 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Заявка</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a class="active" href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Форма заявки на тур</h1>
|
||||
<p>Заполните заявку, и менеджер свяжется с вами для уточнения деталей и подбора оптимального варианта поездки.</p>
|
||||
<div class="card">
|
||||
<form id="bookingForm">
|
||||
<div>
|
||||
<label for="firstName">Имя</label>
|
||||
<input id="firstName" name="firstName" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="lastName">Фамилия</label>
|
||||
<input id="lastName" name="lastName" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="email">Email</label>
|
||||
<input id="email" type="email" name="email" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="phone">Телефон</label>
|
||||
<input id="phone" name="phone" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="city">Город вылета</label>
|
||||
<input id="city" name="city" required>
|
||||
</div>
|
||||
<div>
|
||||
<label for="direction">Направление</label>
|
||||
<select id="direction" name="direction">
|
||||
<option>Турция</option>
|
||||
<option>Италия</option>
|
||||
<option>Норвегия</option>
|
||||
<option>Исландия</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="startDate">Дата начала</label>
|
||||
<input id="startDate" type="date" name="startDate">
|
||||
</div>
|
||||
<div>
|
||||
<label for="endDate">Дата окончания</label>
|
||||
<input id="endDate" type="date" name="endDate">
|
||||
</div>
|
||||
<div>
|
||||
<label for="people">Количество человек</label>
|
||||
<input id="people" type="number" min="1" name="people">
|
||||
</div>
|
||||
<div>
|
||||
<label for="budget">Бюджет (руб.)</label>
|
||||
<input id="budget" type="number" min="10000" name="budget">
|
||||
</div>
|
||||
<div class="form-full">
|
||||
<label for="comment">Комментарий</label>
|
||||
<textarea id="comment" name="comment"></textarea>
|
||||
</div>
|
||||
<div class="form-full">
|
||||
<button class="btn" type="submit">Отправить</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="formResult" class="result">После отправки вы увидите краткую сводку по вашей заявке.</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
49
labWeb/kt_3/cards.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Направления</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a class="active" href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Популярные направления</h1>
|
||||
<p>Подборка направлений для спокойного отдыха, активных поездок и насыщенных экскурсионных программ.</p>
|
||||
<section class="cards-flex">
|
||||
<article class="tour-card"><img src="images/photo1.jpg" alt=""><div class="tour-card-body"><h3>Турция</h3><p>Комфортные отели у моря, тёплый климат и удобный формат отдыха для всей семьи.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo2.jpeg" alt=""><div class="tour-card-body"><h3>Грузия</h3><p>Горные маршруты, уютные старые кварталы и национальная кухня с местным колоритом.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo3.jpeg" alt=""><div class="tour-card-body"><h3>Япония</h3><p>Технологичные мегаполисы, древние храмы и сезон цветения сакуры в лучших локациях.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo4.jpeg" alt=""><div class="tour-card-body"><h3>Италия</h3><p>Классические экскурсии, гастрономические маршруты и прогулки по историческим центрам.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo5.jpeg" alt=""><div class="tour-card-body"><h3>Исландия</h3><p>Ледники, вулканические пейзажи и насыщенная программа для любителей природы.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo6.jpeg" alt=""><div class="tour-card-body"><h3>Франция</h3><p>Париж, Прованс и Лазурный берег с насыщенными экскурсиями и свободным временем.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo7.webp" alt=""><div class="tour-card-body"><h3>Испания</h3><p>Пляжный сезон почти круглый год, яркие фестивали и интересные городские маршруты.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo8.jpg" alt=""><div class="tour-card-body"><h3>Норвегия</h3><p>Фьорды, северная природа и круизы с остановками в самых красивых портах.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo9.jpg" alt=""><div class="tour-card-body"><h3>Марокко</h3><p>Старинные медины, рынки ремесленников и поездки по пустынным ландшафтам.</p></div></article>
|
||||
<article class="tour-card"><img src="images/photo10.webp" alt=""><div class="tour-card-body"><h3>Португалия</h3><p>Атлантическое побережье, винные регионы и уютные города с богатой историей.</p></div></article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
44
labWeb/kt_3/contacts.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Контакты</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a class="active" href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Контакты</h1>
|
||||
<section class="card">
|
||||
<h2>Наш офис</h2>
|
||||
<p>Мы работаем ежедневно и помогаем подобрать туры для отпуска, командировок и семейных поездок.</p>
|
||||
<p><b>Адрес:</b> Москва, ул. Примерная, 10</p>
|
||||
<p><b>Телефон:</b> +7 (900) 123-45-67</p>
|
||||
<p><b>Email:</b> info@tour-example.ru</p>
|
||||
<p id="geoResult"></p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
7
labWeb/kt_3/figma-link.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Макет главной страницы в Figma:
|
||||
https://www.figma.com/file/example123/Vokrug-Sveta-Main-Page
|
||||
|
||||
Описание макета:
|
||||
- Первый экран с заголовком, текущей датой и кнопкой перехода к заявке
|
||||
- Блок с ключевыми преимуществами агентства
|
||||
- Секция со слайдером туристических направлений
|
||||
BIN
labWeb/kt_3/images/photo1.jpg
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
labWeb/kt_3/images/photo10.webp
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
labWeb/kt_3/images/photo2.jpeg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
labWeb/kt_3/images/photo3.jpeg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
labWeb/kt_3/images/photo4.jpeg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
labWeb/kt_3/images/photo5.jpeg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
labWeb/kt_3/images/photo6.jpeg
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
labWeb/kt_3/images/photo7.webp
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
labWeb/kt_3/images/photo8.jpg
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
labWeb/kt_3/images/photo9.jpg
Normal file
|
After Width: | Height: | Size: 77 KiB |
76
labWeb/kt_3/index.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Главная</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a class="active" href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<section class="hero">
|
||||
<h1>Туристическое агентство "Вокруг Света"</h1>
|
||||
<p>Помогаем подобрать поездки под ваш стиль отдыха: от коротких городских уикендов до больших путешествий на 10-14 дней.</p>
|
||||
<p><b>Сегодня:</b> <span id="todayDate"></span></p>
|
||||
<p>Макет главной страницы в Figma: <a href="#" title="Добавьте свою ссылку Figma">посмотреть</a></p>
|
||||
</section>
|
||||
|
||||
<section class="grid-home">
|
||||
<article class="card">
|
||||
<h2>Куда можно поехать</h2>
|
||||
<p>В каталоге есть пляжные, экскурсионные и комбинированные туры с разным бюджетом и длительностью.</p>
|
||||
<p>Мы обновляем подборку каждую неделю, чтобы в ней были только актуальные предложения.</p>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<h2>Быстрые ссылки</h2>
|
||||
<ul>
|
||||
<li><a href="news.html">Открыть новости</a></li>
|
||||
<li><a href="booking.html">Оставить заявку</a></li>
|
||||
<li><a href="contacts.html">Наши контакты</a></li>
|
||||
</ul>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h2>Идеи для следующей поездки</h2>
|
||||
<div class="slider">
|
||||
<div class="slide active">
|
||||
<img src="images/photo1.jpg" alt="Горы">
|
||||
<div class="slide-caption">Горные приключения</div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<img src="images/photo10.webp" alt="Пляж">
|
||||
<div class="slide-caption">Пляжный отдых</div>
|
||||
</div>
|
||||
<div class="slide">
|
||||
<img src="images/photo8.jpg" alt="Город">
|
||||
<div class="slide-caption">Экскурсии по городам</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
97
labWeb/kt_3/news.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Новости</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a class="active" href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Новости туризма</h1>
|
||||
<p>Следим за обновлениями в отрасли и публикуем важные изменения по направлениям, ценам и условиям поездок.</p>
|
||||
<section class="news-grid">
|
||||
<article class="news-item">
|
||||
<img src="images/photo1.jpg" alt="Новость 1">
|
||||
<div class="news-item-content">
|
||||
<h3>Открыт новый маршрут в Исландию</h3>
|
||||
<p>Маршрут включает ледники, водопады и вулканические зоны.</p>
|
||||
<button class="btn open-news" data-title="Открыт новый маршрут в Исландию" data-full="С мая 2026 года запускается недельный тур по Исландии с гидом. Программа включает экскурсии к водопадам, посещение ледниковой лагуны и наблюдение северного сияния в вечернее время.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo2.jpeg" alt="Новость 2">
|
||||
<div class="news-item-content">
|
||||
<h3>Снижены цены на летние туры</h3>
|
||||
<p>Раннее бронирование позволяет сэкономить до 25%.</p>
|
||||
<button class="btn open-news" data-title="Снижены цены на летние туры" data-full="До конца месяца действует акция на летние направления: Турция, Греция и Черногория. При бронировании заранее доступны расширенные условия отмены и бесплатный трансфер от аэропорта.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo3.jpeg" alt="Новость 3">
|
||||
<div class="news-item-content">
|
||||
<h3>Новые экскурсии по историческим местам</h3>
|
||||
<p>Добавлены программы с профессиональными гидами.</p>
|
||||
<button class="btn open-news" data-title="Новые экскурсии по историческим местам" data-full="В разделе экскурсионных туров появились новые маршруты по Европе и Азии. Участники смогут посетить музеи, архитектурные памятники и местные фестивали с русскоязычным сопровождением.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo4.jpeg" alt="Новость 4">
|
||||
<div class="news-item-content">
|
||||
<h3>Запущена программа семейных туров</h3>
|
||||
<p>Специальные условия для семей с детьми до 12 лет.</p>
|
||||
<button class="btn open-news" data-title="Запущена программа семейных туров" data-full="Новая программа ориентирована на спокойный отдых с детьми. В стоимость включены детские активности, анимация в отелях и скидки на второй номер для большой семьи.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo5.jpeg" alt="Новость 5">
|
||||
<div class="news-item-content">
|
||||
<h3>Появились зимние туры на Байкал</h3>
|
||||
<p>Катание на коньках, фототуры и горячие источники.</p>
|
||||
<button class="btn open-news" data-title="Появились зимние туры на Байкал" data-full="Компания подготовила зимнюю программу на Байкале: прозрачный лед, фотосессии, катание на снегоходах и посещение термальных источников. Доступны туры на 5 и 8 дней.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
<article class="news-item">
|
||||
<img src="images/photo6.jpeg" alt="Новость 6">
|
||||
<div class="news-item-content">
|
||||
<h3>Обновлены правила страхования</h3>
|
||||
<p>Включена расширенная медицинская поддержка.</p>
|
||||
<button class="btn open-news" data-title="Обновлены правила страхования" data-full="Во всех пакетных турах теперь действует обновленная страховка. Она покрывает экстренную медицинскую помощь, задержки рейсов и дополнительные расходы при вынужденном продлении поездки.">Читать полностью</button>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="newsModal" class="modal-overlay">
|
||||
<div class="modal">
|
||||
<div class="modal-head">
|
||||
<h2 id="modalTitle">Новость</h2>
|
||||
<button id="closeModal" class="close-btn">Закрыть</button>
|
||||
</div>
|
||||
<p id="modalText"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
117
labWeb/kt_3/script.js
Normal file
@@ -0,0 +1,117 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const burger = document.getElementById("burger");
|
||||
const nav = document.getElementById("siteNav");
|
||||
if (burger && nav) {
|
||||
burger.addEventListener("click", function () {
|
||||
nav.classList.toggle("open");
|
||||
});
|
||||
}
|
||||
|
||||
const dateBox = document.getElementById("todayDate");
|
||||
if (dateBox) {
|
||||
const now = new Date();
|
||||
dateBox.textContent = now.toLocaleDateString("ru-RU", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
weekday: "long"
|
||||
});
|
||||
}
|
||||
|
||||
const slides = Array.from(document.querySelectorAll(".slide"));
|
||||
if (slides.length > 0) {
|
||||
let slideIndex = 0;
|
||||
setInterval(function () {
|
||||
slides[slideIndex].classList.remove("active");
|
||||
slideIndex = (slideIndex + 1) % slides.length;
|
||||
slides[slideIndex].classList.add("active");
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
const newsModal = document.getElementById("newsModal");
|
||||
const modalTitle = document.getElementById("modalTitle");
|
||||
const modalText = document.getElementById("modalText");
|
||||
const closeModalBtn = document.getElementById("closeModal");
|
||||
const newsButtons = document.querySelectorAll(".open-news");
|
||||
|
||||
if (newsModal && modalTitle && modalText && closeModalBtn && newsButtons.length) {
|
||||
newsButtons.forEach(function (btn) {
|
||||
btn.addEventListener("click", function () {
|
||||
modalTitle.textContent = btn.dataset.title || "Новость";
|
||||
modalText.textContent = btn.dataset.full || "";
|
||||
newsModal.classList.add("open");
|
||||
});
|
||||
});
|
||||
|
||||
closeModalBtn.addEventListener("click", function () {
|
||||
newsModal.classList.remove("open");
|
||||
});
|
||||
|
||||
newsModal.addEventListener("click", function (event) {
|
||||
if (event.target === newsModal) {
|
||||
newsModal.classList.remove("open");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const geoBtn = document.getElementById("geoBtn");
|
||||
const geoResult = document.getElementById("geoResult");
|
||||
if (geoBtn && geoResult) {
|
||||
geoBtn.addEventListener("click", function () {
|
||||
if (!navigator.geolocation) {
|
||||
geoResult.textContent = "Геолокация не поддерживается.";
|
||||
return;
|
||||
}
|
||||
geoResult.textContent = "Определяем координаты...";
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
function (position) {
|
||||
const lat = position.coords.latitude.toFixed(5);
|
||||
const lon = position.coords.longitude.toFixed(5);
|
||||
geoResult.textContent = "Ваши координаты: " + lat + ", " + lon;
|
||||
},
|
||||
function () {
|
||||
geoResult.textContent = "Не удалось получить геолокацию.";
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const bookingForm = document.getElementById("bookingForm");
|
||||
const formResult = document.getElementById("formResult");
|
||||
if (bookingForm && formResult) {
|
||||
const saved = localStorage.getItem("bookingData");
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved);
|
||||
for (const key in parsed) {
|
||||
const el = bookingForm.elements[key];
|
||||
if (el) {
|
||||
el.value = parsed[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bookingForm.addEventListener("submit", function (event) {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(bookingForm);
|
||||
const dataObj = {};
|
||||
formData.forEach(function (value, key) {
|
||||
dataObj[key] = value;
|
||||
});
|
||||
|
||||
localStorage.setItem("bookingData", JSON.stringify(dataObj));
|
||||
formResult.innerHTML =
|
||||
"<h3>Результат обработки формы</h3>" +
|
||||
"<p><b>Имя:</b> " + (dataObj.firstName || "") + "</p>" +
|
||||
"<p><b>Фамилия:</b> " + (dataObj.lastName || "") + "</p>" +
|
||||
"<p><b>Email:</b> " + (dataObj.email || "") + "</p>" +
|
||||
"<p><b>Телефон:</b> " + (dataObj.phone || "") + "</p>" +
|
||||
"<p><b>Город вылета:</b> " + (dataObj.city || "") + "</p>" +
|
||||
"<p><b>Направление:</b> " + (dataObj.direction || "") + "</p>" +
|
||||
"<p><b>Дата старта:</b> " + (dataObj.startDate || "") + "</p>" +
|
||||
"<p><b>Дата возврата:</b> " + (dataObj.endDate || "") + "</p>" +
|
||||
"<p><b>Количество человек:</b> " + (dataObj.people || "") + "</p>" +
|
||||
"<p><b>Бюджет:</b> " + (dataObj.budget || "") + " руб.</p>" +
|
||||
"<p><b>Комментарий:</b> " + (dataObj.comment || "") + "</p>";
|
||||
});
|
||||
}
|
||||
});
|
||||
375
labWeb/kt_3/styles.css
Normal file
@@ -0,0 +1,375 @@
|
||||
:root {
|
||||
--bg: #f6f7fb;
|
||||
--card: #ffffff;
|
||||
--text: #222;
|
||||
--muted: #667085;
|
||||
--accent: #3b82f6;
|
||||
--accent-dark: #1d4ed8;
|
||||
--border: #e5e7eb;
|
||||
--shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Arial, sans-serif;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: min(1100px, 92%);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.site-header {
|
||||
background: #0f172a;
|
||||
color: #fff;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 30;
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.burger {
|
||||
display: none;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.site-nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 18px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.site-nav a {
|
||||
color: #fff;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.site-nav a:hover,
|
||||
.site-nav a.active {
|
||||
opacity: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-top: 20px;
|
||||
background: linear-gradient(120deg, #dbeafe, #f0f9ff);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
padding: 26px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.grid-home {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 18px;
|
||||
margin: 20px 0 30px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.slider {
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
.slide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.slide.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slide img {
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.slide-caption {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 9px 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--accent-dark);
|
||||
}
|
||||
|
||||
.news-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
border: 1px solid var(--border);
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.news-item img {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-item-content {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.cards-flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 14px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: calc(25% - 11px);
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tour-card img {
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.tour-card-body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #e2e8f0;
|
||||
}
|
||||
|
||||
form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: var(--muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 7px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 90px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.form-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin-top: 16px;
|
||||
background: #fff;
|
||||
border: 1px dashed #94a3b8;
|
||||
border-radius: 10px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.map-wrap iframe {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
z-index: 100;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.modal-overlay.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal {
|
||||
width: min(720px, 100%);
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.modal-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
border: 0;
|
||||
background: #e2e8f0;
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
margin-top: 30px;
|
||||
background: #0f172a;
|
||||
color: #fff;
|
||||
padding: 14px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
.news-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
width: calc(33.333% - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.burger {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #0f172a;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
|
||||
.site-nav.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.site-nav ul {
|
||||
flex-direction: column;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.grid-home {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.news-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.tour-card {
|
||||
width: calc(50% - 7px);
|
||||
}
|
||||
|
||||
form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.tour-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
58
labWeb/kt_3/tours.html
Normal file
@@ -0,0 +1,58 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Вокруг Света | Расписание</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container header-inner">
|
||||
<a class="logo" href="index.html">Вокруг Света</a>
|
||||
<button id="burger" class="burger" aria-label="Меню">☰</button>
|
||||
<nav id="siteNav" class="site-nav">
|
||||
<ul>
|
||||
<li><a href="index.html">Главная</a></li>
|
||||
<li><a href="news.html">Новости</a></li>
|
||||
<li><a href="cards.html">Направления</a></li>
|
||||
<li><a class="active" href="tours.html">Расписание</a></li>
|
||||
<li><a href="booking.html">Заявка</a></li>
|
||||
<li><a href="contacts.html">Контакты</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<h1>Расписание туров на месяц</h1>
|
||||
<p>Ниже представлены ближайшие выезды по популярным направлениям с актуальными ценами и количеством свободных мест.</p>
|
||||
<div class="card">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Дата</th>
|
||||
<th>Направление</th>
|
||||
<th>Длительность</th>
|
||||
<th>Цена</th>
|
||||
<th>Свободные места</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>05.05.2026</td><td>Турция</td><td>7 дней</td><td>58 000</td><td>12</td></tr>
|
||||
<tr><td>08.05.2026</td><td>Италия</td><td>8 дней</td><td>84 000</td><td>6</td></tr>
|
||||
<tr><td>10.05.2026</td><td>Грузия</td><td>6 дней</td><td>49 000</td><td>9</td></tr>
|
||||
<tr><td>13.05.2026</td><td>Франция</td><td>9 дней</td><td>102 000</td><td>4</td></tr>
|
||||
<tr><td>17.05.2026</td><td>Исландия</td><td>7 дней</td><td>120 000</td><td>5</td></tr>
|
||||
<tr><td>20.05.2026</td><td>Норвегия</td><td>8 дней</td><td>111 000</td><td>7</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">ООО "Вокруг Света" | Москва, ул. Примерная, 10 | +7 (900) 123-45-67 | info@tour-example.ru</div>
|
||||
</footer>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
84
labWeb/lab3/index.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Озеро Байкал</title>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="page">
|
||||
<main class="card">
|
||||
<header class="card__header">
|
||||
<h1 class="title">Озеро Байкал</h1>
|
||||
</header>
|
||||
|
||||
<section class="card__body" aria-label="Информация об озере Байкал">
|
||||
<p class="p p--highlight">
|
||||
<strong>Байкал</strong> (бур. <em>Байгал далай</em>) — озеро тектонического происхождения в южной части
|
||||
Восточной Сибири площадью 31 722 км², самое глубокое озеро на планете, крупнейший природный резервуар пресной
|
||||
воды и самое большое по площади пресноводное озеро Евразии.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Находится в центре Азии на границе
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%98%D1%80%D0%BA%D1%83%D1%82%D1%81%D0%BA%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BB%D0%B0%D1%81%D1%82%D1%8C" target="_blank" rel="noreferrer noopener"
|
||||
>Иркутской области</a
|
||||
>
|
||||
и
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%81%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0_%D0%91%D1%83%D1%80%D1%8F%D1%82%D0%B8%D1%8F" target="_blank" rel="noreferrer noopener"
|
||||
>Республики Бурятия</a
|
||||
>
|
||||
в Российской Федерации. Озеро протянулось с юго-запада на северо-восток на 636 км в виде гигантского
|
||||
полумесяца. Ширина водоёма колеблется в пределах от 24 до 79 км. Дно Байкала в самой глубокой его части на
|
||||
1187 метров ниже уровня Мирового океана. Высотная отметка уреза воды Байкала установлена (так как Байкал
|
||||
зарегулирован) в пределе 456—457 метров над уровнем моря, но в Тихоокеанской системе высот. В результате
|
||||
«реальный» уровень Байкала фактически неизвестен.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Площадь водной поверхности Байкала — 31 722 км² (без учёта островов), что примерно равно площади таких стран,
|
||||
как Бельгия или Нидерланды. По площади водного зеркала Байкал занимает седьмое место среди крупнейших озёр
|
||||
мира. Площадь водосборного бассейна — 571 тыс. км². Длина береговой линии — 2000 км.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Озеро находится в своеобразной котловине, со всех сторон окружённой горными хребтами и сопками. При этом
|
||||
западное побережье — скалистое и обрывистое, рельеф восточного побережья — более пологий (местами горы
|
||||
отступают от берега на десятки километров).
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
Запасы воды в Байкале гигантские — <strong>23 615,39 км³</strong> (около <em>19 %</em> от 123 тыс. км³ всех мировых запасов
|
||||
озёрной пресной воды). По объёму запасов пресной воды Байкал занимает первое место в мире среди озёр. В Байкале
|
||||
воды больше, чем во всех вместе взятых пяти
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%92%D0%B5%D0%BB%D0%B8%D0%BA%D0%B8%D0%B5_%D0%BE%D0%B7%D1%91%D1%80%D0%B0" target="_blank" rel="noreferrer noopener"
|
||||
>Великих озёрах</a
|
||||
>
|
||||
Северной Америки (Верхнее, Мичиган, Гурон, Эри, Онтарио), и в 25 раз больше, чем в Ладожском озере. Если же
|
||||
брать абсолютную величину среди всех озёр мира, то Байкал по объёму воды уступает разве что
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%81%D0%BF%D0%B8%D0%B9%D1%81%D0%BA%D0%BE%D0%B5_%D0%BC%D0%BE%D1%80%D0%B5" target="_blank" rel="noreferrer noopener"
|
||||
>Каспийскому морю</a
|
||||
>.
|
||||
</p>
|
||||
|
||||
<p class="p">
|
||||
По данным исследований И. Д. Черского (XIX век) в Байкал впадало 336 рек и ручьё, и это число учитывало
|
||||
только постоянные притоки. Более современных данных по данному вопросу нет, однако иногда приводятся цифры в
|
||||
544 или 1123 (которые приведены в результате подсчёта распадков, а не постоянных водотоков). Также считается,
|
||||
что вследствие антропогенного воздействия и изменения климата на Байкале с XIX века по современное время
|
||||
могло пропасть порядка 150 водотоков.
|
||||
</p>
|
||||
|
||||
<p class="p p--highlight">
|
||||
Самые крупные реки, впадающие в Байкал — это Селенга, Верхняя Ангара, Баргузин, Турка, Снежная, Кичера, Тыя,
|
||||
Голоустная, Бугульдейка. Из озера вытекает только одна река —
|
||||
<a class="a" href="https://ru.wikipedia.org/wiki/%D0%90%D0%BD%D0%B3%D0%B0%D1%80%D0%B0" target="_blank" rel="noreferrer noopener"
|
||||
>Ангара</a
|
||||
>.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
89
labWeb/lab3/style.css
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
:root {
|
||||
--maroon: #9f2b2b;
|
||||
--maroon-dark: #7e1f1f;
|
||||
--paper: #ffffff;
|
||||
--highlight: #f7e3c1;
|
||||
--text: #111111;
|
||||
--link: #6b3e1e;
|
||||
--link-hover: #b84c1b;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 24px 0;
|
||||
background: var(--paper);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.page {
|
||||
width: min(980px, calc(100% - 32px));
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin: 0 0 10px;
|
||||
font: 700 14pt/1.2 "Times New Roman", Times, serif;
|
||||
color: var(--maroon);
|
||||
}
|
||||
|
||||
.card {
|
||||
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.card__header {
|
||||
padding: 10px 14px;
|
||||
background: var(--maroon);
|
||||
border-bottom: 2px solid var(--maroon-dark);
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-family: Cambria, Georgia, "Times New Roman", serif;
|
||||
font-size: 24pt;
|
||||
line-height: 1.1;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.card__body {
|
||||
padding: 10px 12px 12px;
|
||||
}
|
||||
|
||||
.p {
|
||||
margin: 0 0 10px;
|
||||
font-family: "Times New Roman", Times, serif;
|
||||
font-size: 14pt;
|
||||
line-height: 1.35;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.p--highlight {
|
||||
background: var(--highlight);
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.a {
|
||||
color: var(--link);
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 2px;
|
||||
transition: color 120ms ease-in-out;
|
||||
}
|
||||
|
||||
.a:hover,
|
||||
.a:focus-visible {
|
||||
color: var(--link-hover);
|
||||
}
|
||||
|
||||
194
labWeb/lab4-6/contacts.html
Normal file
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Контакты | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800">Контакты</h2>
|
||||
<p class="text-slate-600 mt-2">Мы всегда рады помочь вам. Свяжитесь с нами удобным способом.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid lg:grid-cols-2 gap-8">
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="map-pin" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Адрес</h3>
|
||||
<p class="text-slate-600">г. Москва, ул. Здоровья, д. 15, корп. 2</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Ближайшее метро: Медицинская (5 мин. пешком)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="phone" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Телефоны</h3>
|
||||
<p class="text-slate-600 text-lg font-medium">+7 (495) 123-45-67</p>
|
||||
<p class="text-slate-600">+7 (495) 987-65-43</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Единый колл-центр: круглосуточно</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4 mb-6">
|
||||
<div class="w-12 h-12 bg-rose-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="mail" class="w-6 h-6 text-rose-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Email</h3>
|
||||
<p class="text-slate-600">info@medsave.ru</p>
|
||||
<p class="text-slate-600">appointments@medsave.ru</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start space-x-4">
|
||||
<div class="w-12 h-12 bg-amber-100 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="clock" class="w-6 h-6 text-amber-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-1">Режим работы</h3>
|
||||
<p class="text-slate-600">Пн-Пт: 8:00 - 20:00</p>
|
||||
<p class="text-slate-600">Сб-Вс: 9:00 - 18:00</p>
|
||||
<p class="text-slate-500 text-sm mt-1">Без выходных</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-4">Мы в соцсетях и мессенджерах</h3>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-blue-400 text-white rounded-lg hover:bg-blue-500 transition">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
<span>Telegram</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
<span>WhatsApp</span>
|
||||
</a>
|
||||
<a href="#" class="flex items-center space-x-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition">
|
||||
<i data-lucide="smartphone" class="w-5 h-5"></i>
|
||||
<span>Viber</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="space-y-6">
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden border border-slate-100">
|
||||
<img src="https://static.photos/medical/1024x576/501" alt="Здание клиники МедСэйв" class="w-full h-80 object-cover">
|
||||
<div class="p-6">
|
||||
<h3 class="font-semibold text-lg text-slate-800 mb-2">Наша клиника</h3>
|
||||
<p class="text-slate-600 text-sm">Современное здание медицинского центра оснащено всем необходимым для комфортного приема пациентов. Доступно бесплатная парковка для клиентов.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-br from-sky-500 to-blue-600 rounded-2xl shadow-lg p-6 text-white">
|
||||
<h3 class="font-semibold text-lg mb-4">Экстренная помощь</h3>
|
||||
<p class="text-sky-100 mb-4 text-sm">При острых состояниях звоните на горячую линию немедленно:</p>
|
||||
<div class="flex items-center space-x-3 text-2xl font-bold">
|
||||
<i data-lucide="phone-call" class="w-8 h-8"></i>
|
||||
<span>+7 (495) 123-45-67</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-slate-300">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в соцсетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
227
labWeb/lab4-6/doctors.html
Normal file
@@ -0,0 +1,227 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Наши врачи | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
|
||||
ol.doctor-categories {
|
||||
list-style: none;
|
||||
counter-reset: category;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ol.doctor-categories > li {
|
||||
counter-increment: category;
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
ol.doctor-categories > li::before {
|
||||
content: counter(category);
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-image: url('https://static.photos/medical/200x200/777');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
margin-right: 12px;
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
font-size: 14px;
|
||||
text-shadow: 0 1px 2px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
|
||||
ul.doctor-list {
|
||||
list-style: none;
|
||||
padding-left: 3rem;
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
ul.doctor-list li {
|
||||
position: relative;
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
ul.doctor-list li::before {
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
color: #0ea5e9;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Наши специалисты</h2>
|
||||
<p class="text-slate-600">Квалифицированные врачи с многолетним опытом работы</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 border border-slate-100">
|
||||
<ol class="doctor-categories">
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Терапевты</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Иванов И.И.</li>
|
||||
<li>Сидорова Е.Л.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Неврологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Петрова Л.Д.</li>
|
||||
<li>Орлова Г.Д.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">УЗИ-специалисты</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Гордеев О.Т.</li>
|
||||
<li>Арбатова Е.К.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Кардиологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Смирнов А.В.</li>
|
||||
<li>Козлова Н.П.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Эндокринологи</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Морозов П.С.</li>
|
||||
<li>Васильева Т.А.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span class="text-xl font-semibold text-slate-800">Хирурги</span>
|
||||
<ul class="doctor-list">
|
||||
<li>Новиков Д.Г.</li>
|
||||
<li>Лебедева С.М.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gradient-to-br from-sky-500 to-blue-600 rounded-2xl shadow-lg p-6 text-white">
|
||||
<h3 class="font-semibold text-lg mb-3 flex items-center gap-2">
|
||||
<i data-lucide="graduation-cap" class="w-5 h-5"></i>
|
||||
Высшая категория
|
||||
</h3>
|
||||
<p class="text-sky-100 text-sm">Более 70% наших врачей имеют высшую и первую квалификационную категорию.</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 border border-slate-100">
|
||||
<h3 class="font-semibold text-lg mb-3 flex items-center gap-2 text-slate-800">
|
||||
<i data-lucide="calendar-check" class="w-5 h-5 text-sky-600"></i>
|
||||
Запись к врачу
|
||||
</h3>
|
||||
<p class="text-slate-600 text-sm mb-4">Запишитесь на прием к нужному специалисту через наш колл-центр.</p>
|
||||
<a href="contacts.html" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Перейти к контактам <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
200
labWeb/lab4-6/index.html
Normal file
@@ -0,0 +1,200 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>МедСэйв - Главная | Медицинский центр</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
.glass-effect { background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(10px); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
|
||||
|
||||
<section class="mb-12">
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="stethoscope" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Профессиональная диагностика</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Современное оборудование и квалифицированные специалисты для точной постановки диагноза и эффективного лечения.</p>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="shield-check" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Безопасность и забота</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Индивидуальный подход к каждому пациенту, строгие санитарные нормы и комфортная обстановка в клинике.</p>
|
||||
</div>
|
||||
|
||||
<div class="glass-effect rounded-2xl p-6 shadow-lg border border-slate-200 hover:shadow-xl transition">
|
||||
<div class="w-12 h-12 bg-rose-100 rounded-xl flex items-center justify-center mb-4">
|
||||
<i data-lucide="clock" class="w-6 h-6 text-rose-600"></i>
|
||||
</div>
|
||||
<h3 class="text-lg font-semibold mb-2 text-slate-800">Удобное расписание</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">Работаем ежедневно без выходных. Запись на прием онлайн и по телефону. Минимальное время ожидания.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800">Новости клиники</h2>
|
||||
<span class="bg-sky-100 text-sky-700 px-3 py-1 rounded-full text-sm font-medium">Актуальное</span>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/101" alt="Новое оборудование" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>15 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Новое диагностическое оборудование</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">В нашей клинике установлен современный аппарат УЗИ экспертного класса. Теперь диагностика стала еще точнее и комфортнее для пациентов.</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/202" alt="Новый врач" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>10 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Пополнение в команде специалистов</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">Врач-невролог Петрова Людмила Дмитриевна присоединилась к нашей команде. Записаться на консультацию можно уже сейчас.</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
|
||||
<article class="bg-white rounded-2xl shadow-lg overflow-hidden hover:shadow-2xl transition duration-300 border border-slate-100">
|
||||
<div class="h-48 overflow-hidden">
|
||||
<img src="https://static.photos/medical/640x360/303" alt="Акция" class="w-full h-full object-cover hover:scale-105 transition duration-500">
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="flex items-center gap-2 mb-3 text-sm text-slate-500">
|
||||
<i data-lucide="calendar" class="w-4 h-4"></i>
|
||||
<span>5 января 2024</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3 text-slate-800 hover:text-sky-600 transition">Акция: комплексное обследование</h3>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-4">В январе действует скидка 20% на комплексное обследование организма. Успейте позаботиться о своем здоровье выгодно!</p>
|
||||
<a href="#" class="inline-flex items-center text-sky-600 font-medium hover:text-sky-700 transition">
|
||||
Подробнее <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
const menu = document.getElementById('mobileMenu');
|
||||
menu.classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
<script src="https://deepsite.hf.co/deepsite-badge.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
214
labWeb/lab4-6/prices.html
Normal file
@@ -0,0 +1,214 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Цены на услуги | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
ol.medical-list {
|
||||
counter-reset: item;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
ol.medical-list > li {
|
||||
counter-increment: item;
|
||||
position: relative;
|
||||
padding-left: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
ol.medical-list > li::before {
|
||||
content: counter(item);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<div class="mb-8 text-center">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Прайс-лист на услуги</h2>
|
||||
<p class="text-slate-600">Актуальные цены на медицинские услуги клиники МедСэйв</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 border border-slate-100">
|
||||
<div class="flex items-center gap-3 mb-6 pb-6 border-b border-slate-100">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-xl flex items-center justify-center">
|
||||
<i data-lucide="banknote" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg text-slate-800">Стоимость консультаций и процедур</h3>
|
||||
<p class="text-sm text-slate-500">Цены указаны в рублях (₽)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ol class="medical-list space-y-4">
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Первичная консультация терапевта</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Осмотр, назначение лечения, рекомендации</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">2 500 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Повторная консультация терапевта</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Корректировка лечения, контроль динамики</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 800 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Консультация невролога</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Неврологическое обследование, рекомендации</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">3 200 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">УЗИ органов брюшной полости</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Комплексное обследование печени, желчного, селезенки</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">2 800 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">УЗИ щитовидной железы</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Оценка структуры и размеров железы</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 500 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">ЭКГ с расшифровкой</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Электрокардиография с заключением врача</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">1 200 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Общий анализ крови</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Забор крови из вены, лабораторное исследование</p>
|
||||
</div>
|
||||
<span class="font-bold text-sky-600 text-lg">650 ₽</span>
|
||||
</li>
|
||||
|
||||
<li class="flex justify-between items-center p-4 bg-slate-50 rounded-xl hover:bg-sky-50 transition group">
|
||||
<div>
|
||||
<span class="font-medium text-slate-800 group-hover:text-sky-700">Комплексное обследование (Check-up)</span>
|
||||
<p class="text-sm text-slate-500 mt-1">Полное обследование организма (консультации + анализы)</p>
|
||||
</div>
|
||||
<span class="font-bold text-emerald-600 text-lg">15 000 ₽</span>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<div class="mt-8 p-4 bg-amber-50 border border-amber-200 rounded-xl flex items-start gap-3">
|
||||
<i data-lucide="info" class="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5"></i>
|
||||
<p class="text-sm text-amber-800">
|
||||
<strong>Важно:</strong> Цены могут изменяться. Уточняйте актуальную стоимость при записи на прием.
|
||||
Действуют скидки для пенсионеров и инвалидов — 10% на все услуги.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
317
labWeb/lab4-6/schedule.html
Normal file
@@ -0,0 +1,317 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Расписание специалистов | МедСэйв</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', sans-serif; }
|
||||
.gradient-bg { background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%); }
|
||||
.medical-pattern { background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0); background-size: 20px 20px; }
|
||||
|
||||
|
||||
.schedule-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.schedule-table th {
|
||||
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.schedule-table td {
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.schedule-table tr:hover td {
|
||||
background-color: #f8fafc;
|
||||
}
|
||||
|
||||
.schedule-table tr:nth-child(even) {
|
||||
background-color: #f1f5f9;
|
||||
}
|
||||
|
||||
.cell-merged {
|
||||
background-color: #e0f2fe;
|
||||
font-weight: 600;
|
||||
color: #0369a1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.time-slot {
|
||||
font-family: monospace;
|
||||
color: #64748b;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-800">
|
||||
|
||||
|
||||
<header class="bg-sky-100 medical-pattern text-sky-900 shadow-lg sticky top-0 z-50">
|
||||
<div class="container mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center space-x-3">
|
||||
<div class="bg-sky-200 p-2 rounded-xl">
|
||||
<i data-lucide="heart-pulse" class="w-8 h-8 text-sky-700"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold tracking-tight">МедСэйв</h1>
|
||||
<p class="text-sky-600 text-sm">Медицинский центр</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="hidden md:flex items-center space-x-1">
|
||||
<a href="index.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="px-4 py-2 rounded-lg bg-sky-200 font-medium transition hover:bg-sky-300 text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="px-4 py-2 rounded-lg hover:bg-sky-200 transition text-sky-900">Контакты</a>
|
||||
</nav>
|
||||
|
||||
<button onclick="toggleMobileMenu()" class="md:hidden p-2 rounded-lg bg-sky-200 hover:bg-sky-300 transition text-sky-900">
|
||||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="mobileMenu" class="hidden md:hidden mt-4 pb-4 space-y-2 border-t border-sky-300 pt-4">
|
||||
<a href="index.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Новости</a>
|
||||
<a href="doctors.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Наши врачи</a>
|
||||
<a href="prices.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Цены</a>
|
||||
<a href="schedule.html" class="block px-4 py-2 rounded-lg bg-sky-200 font-medium text-sky-900">Расписание</a>
|
||||
<a href="contacts.html" class="block px-4 py-2 rounded-lg hover:bg-sky-200 text-sky-900">Контакты</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container mx-auto px-4 py-8 max-w-6xl">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-slate-800 mb-2">Расписание приема специалистов</h2>
|
||||
<p class="text-slate-600">График работы врачей на текущую неделю</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-2xl shadow-lg overflow-hidden border border-slate-100">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="schedule-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-tl-2xl">Специальность</th>
|
||||
<th>Врач</th>
|
||||
<th>Понедельник</th>
|
||||
<th>Вторник</th>
|
||||
<th>Среда</th>
|
||||
<th>Четверг</th>
|
||||
<th>Пятница</th>
|
||||
<th class="rounded-tr-2xl">Выходные</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">Терапевты</td>
|
||||
<td class="font-medium">Иванов И.И.</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td rowspan="6" class="cell-merged text-center">
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<i data-lucide="calendar-x" class="w-8 h-8 text-sky-400"></i>
|
||||
<span>Приема нет</span>
|
||||
<span class="text-xs font-normal text-slate-500">(только экстренные случаи)</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Сидорова Е.Л.</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
<td class="time-slot">09:00-13:00</td>
|
||||
<td class="time-slot">14:00-18:00</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">Неврологи</td>
|
||||
<td class="font-medium">Петрова Л.Д.</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Орлова Г.Д.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">10:00-16:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200">УЗИ</td>
|
||||
<td class="font-medium">Гордеев О.Т</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
08:00-14:00
|
||||
</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
08:00-14:00
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Арбатова Е.К.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td colspan="2" class="text-center text-emerald-600 font-medium bg-emerald-50">
|
||||
<i data-lucide="check-circle" class="w-4 h-4 inline mr-1"></i>
|
||||
12:00-18:00
|
||||
</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">12:00-16:00</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="cell-merged border-r-2 border-sky-200">Кардиологи</td>
|
||||
<td class="font-medium">Смирнов А.В.</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="time-slot">09:00-15:00</td>
|
||||
<td class="cell-merged text-center text-slate-400">
|
||||
<i data-lucide="x-circle" class="w-5 h-5 inline"></i>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td rowspan="2" class="cell-merged border-r-2 border-sky-200 rounded-bl-2xl">Эндокринологи</td>
|
||||
<td class="font-medium">Морозов П.С.</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td rowspan="2" class="cell-merged text-center rounded-br-2xl text-slate-400">
|
||||
<i data-lucide="x-circle" class="w-5 h-5 inline"></i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">Васильева Т.А.</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
<td class="time-slot">11:00-17:00</td>
|
||||
<td class="time-slot text-slate-400">—</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="p-6 bg-slate-50 border-t border-slate-200">
|
||||
<div class="flex flex-wrap gap-6 text-sm text-slate-600">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-4 h-4 bg-emerald-50 border border-emerald-200 rounded"></div>
|
||||
<span>Усиленный прием</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-4 h-4 bg-sky-100 border border-sky-200 rounded"></div>
|
||||
<span>Специальность (объединение строк)</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-slate-400">—</span>
|
||||
<span>Выходной день врача</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid md:grid-cols-3 gap-6">
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-amber-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="alert-circle" class="w-6 h-6 text-amber-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Важно</h4>
|
||||
<p class="text-sm text-slate-600">Расписание может меняться. Уточняйте актуальное время по телефону.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-sky-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="phone" class="w-6 h-6 text-sky-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Запись по телефону</h4>
|
||||
<p class="text-sm text-slate-600">+7 (495) 123-45-67 (круглосуточно)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white rounded-xl shadow p-6 border border-slate-100 flex items-start gap-4">
|
||||
<div class="w-12 h-12 bg-emerald-100 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="globe" class="w-6 h-6 text-emerald-600"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="font-semibold text-slate-800 mb-1">Онлайн-запись</h4>
|
||||
<p class="text-sm text-slate-600">Доступна через сайт и мобильное приложение</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="bg-slate-900 text-slate-300 mt-16">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
|
||||
<div class="flex items-center space-x-3">
|
||||
<i data-lucide="heart-pulse" class="w-6 h-6 text-sky-400"></i>
|
||||
<span class="font-semibold text-white">МедСэйв</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-slate-300 mb-2 md:mb-0">
|
||||
<i data-lucide="phone" class="w-4 h-4 text-sky-400"></i>
|
||||
<span class="font-medium text-white">+7 (123) 123-12-31</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm">Мы в социальных сетях:</span>
|
||||
<div class="flex space-x-3">
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-sky-500 hover:text-white transition" title="Telegram">
|
||||
<i data-lucide="send" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-green-500 hover:text-white transition" title="WhatsApp">
|
||||
<i data-lucide="message-circle" class="w-5 h-5"></i>
|
||||
</a>
|
||||
<a href="#" class="w-10 h-10 rounded-full bg-slate-800 flex items-center justify-center hover:bg-purple-600 hover:text-white transition" title="Viber">
|
||||
<i data-lucide="phone-call" class="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-slate-500">© 2024 МедСэйв. Все права защищены.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
lucide.createIcons();
|
||||
function toggleMobileMenu() {
|
||||
document.getElementById('mobileMenu').classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
29
labWeb/lab4-6/style.css
Normal file
@@ -0,0 +1,29 @@
|
||||
body {
|
||||
padding: 2rem;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 16px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgb(107, 114, 128);
|
||||
font-size: 15px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.card {
|
||||
max-width: 620px;
|
||||
margin: 0 auto;
|
||||
padding: 16px;
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.card p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
22
labWeb/lab7/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
let express = require(`express`);
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
app.listen(port, function () {
|
||||
console.log(`http://localhost:${port}`);
|
||||
});
|
||||
app.use(express.static(`public`));
|
||||
|
||||
const hbs = require(`hbs`);
|
||||
app.set(`views`, `views`);
|
||||
app.set(`view engine`, `hbs`);
|
||||
|
||||
console.log(4*32*1000*2*60*32/2**23);
|
||||
|
||||
app.get("/", function (req, res) {
|
||||
res.render("main");
|
||||
});
|
||||
|
||||
app.get("/hf", function (req, res) {
|
||||
res.render("head_and_footer");
|
||||
});
|
||||
1
labWeb/lab7/node_modules/.bin/handlebars
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../handlebars/bin/handlebars
|
||||
17
labWeb/lab7/node_modules/.bin/handlebars.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\handlebars\bin\handlebars" %*
|
||||
28
labWeb/lab7/node_modules/.bin/handlebars.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../handlebars/bin/handlebars" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/mime
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../mime/cli.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/mime.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/mime.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/nodemon
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../nodemon/bin/nodemon.js
|
||||
17
labWeb/lab7/node_modules/.bin/nodemon.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nodemon\bin\nodemon.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nodemon.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nodemon/bin/nodemon.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/nodetouch
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../touch/bin/nodetouch.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/nodetouch.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\touch\bin\nodetouch.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nodetouch.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../touch/bin/nodetouch.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/nopt
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../nopt/bin/nopt.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../nopt/bin/nopt.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/nopt.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nopt\bin\nopt.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/nopt.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../nopt/bin/nopt.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/npm
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../npm/bin/npm-cli.js
|
||||
17
labWeb/lab7/node_modules/.bin/npm.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\npm\bin\npm-cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/npm.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../npm/bin/npm-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/npx
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../npm/bin/npx-cli.js
|
||||
17
labWeb/lab7/node_modules/.bin/npx.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\npm\bin\npx-cli.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/npx.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../npm/bin/npx-cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
12
labWeb/lab7/node_modules/.bin/semver
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../semver/bin/semver.js" "$@"
|
||||
fi
|
||||
17
labWeb/lab7/node_modules/.bin/semver.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
|
||||
28
labWeb/lab7/node_modules/.bin/semver.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
1
labWeb/lab7/node_modules/.bin/uglifyjs
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../uglify-js/bin/uglifyjs
|
||||
17
labWeb/lab7/node_modules/.bin/uglifyjs.cmd
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\uglify-js\bin\uglifyjs" %*
|
||||
28
labWeb/lab7/node_modules/.bin/uglifyjs.ps1
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../uglify-js/bin/uglifyjs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
3609
labWeb/lab7/node_modules/.package-lock.json
generated
vendored
Normal file
46
labWeb/lab7/node_modules/abbrev/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
This software is dual-licensed under the ISC and MIT licenses.
|
||||
You may use this software under EITHER of the following licenses.
|
||||
|
||||
----------
|
||||
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
----------
|
||||
|
||||
Copyright Isaac Z. Schlueter and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
23
labWeb/lab7/node_modules/abbrev/README.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# abbrev-js
|
||||
|
||||
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
|
||||
|
||||
Usage:
|
||||
|
||||
var abbrev = require("abbrev");
|
||||
abbrev("foo", "fool", "folding", "flop");
|
||||
|
||||
// returns:
|
||||
{ fl: 'flop'
|
||||
, flo: 'flop'
|
||||
, flop: 'flop'
|
||||
, fol: 'folding'
|
||||
, fold: 'folding'
|
||||
, foldi: 'folding'
|
||||
, foldin: 'folding'
|
||||
, folding: 'folding'
|
||||
, foo: 'foo'
|
||||
, fool: 'fool'
|
||||
}
|
||||
|
||||
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.
|
||||
61
labWeb/lab7/node_modules/abbrev/abbrev.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
module.exports = exports = abbrev.abbrev = abbrev
|
||||
|
||||
abbrev.monkeyPatch = monkeyPatch
|
||||
|
||||
function monkeyPatch () {
|
||||
Object.defineProperty(Array.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(this) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
|
||||
Object.defineProperty(Object.prototype, 'abbrev', {
|
||||
value: function () { return abbrev(Object.keys(this)) },
|
||||
enumerable: false, configurable: true, writable: true
|
||||
})
|
||||
}
|
||||
|
||||
function abbrev (list) {
|
||||
if (arguments.length !== 1 || !Array.isArray(list)) {
|
||||
list = Array.prototype.slice.call(arguments, 0)
|
||||
}
|
||||
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
|
||||
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
|
||||
}
|
||||
|
||||
// sort them lexicographically, so that they're next to their nearest kin
|
||||
args = args.sort(lexSort)
|
||||
|
||||
// walk through each, seeing how much it has in common with the next and previous
|
||||
var abbrevs = {}
|
||||
, prev = ""
|
||||
for (var i = 0, l = args.length ; i < l ; i ++) {
|
||||
var current = args[i]
|
||||
, next = args[i + 1] || ""
|
||||
, nextMatches = true
|
||||
, prevMatches = true
|
||||
if (current === next) continue
|
||||
for (var j = 0, cl = current.length ; j < cl ; j ++) {
|
||||
var curChar = current.charAt(j)
|
||||
nextMatches = nextMatches && curChar === next.charAt(j)
|
||||
prevMatches = prevMatches && curChar === prev.charAt(j)
|
||||
if (!nextMatches && !prevMatches) {
|
||||
j ++
|
||||
break
|
||||
}
|
||||
}
|
||||
prev = current
|
||||
if (j === cl) {
|
||||
abbrevs[current] = current
|
||||
continue
|
||||
}
|
||||
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
|
||||
abbrevs[a] = current
|
||||
a += current.charAt(j)
|
||||
}
|
||||
}
|
||||
return abbrevs
|
||||
}
|
||||
|
||||
function lexSort (a, b) {
|
||||
return a === b ? 0 : a > b ? 1 : -1
|
||||
}
|
||||
21
labWeb/lab7/node_modules/abbrev/package.json
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "abbrev",
|
||||
"version": "1.1.1",
|
||||
"description": "Like ruby's abbrev module, but in js",
|
||||
"author": "Isaac Z. Schlueter <i@izs.me>",
|
||||
"main": "abbrev.js",
|
||||
"scripts": {
|
||||
"test": "tap test.js --100",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags"
|
||||
},
|
||||
"repository": "http://github.com/isaacs/abbrev-js",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"tap": "^10.1"
|
||||
},
|
||||
"files": [
|
||||
"abbrev.js"
|
||||
]
|
||||
}
|
||||
243
labWeb/lab7/node_modules/accepts/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
1.3.8 / 2022-02-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.34
|
||||
- deps: mime-db@~1.51.0
|
||||
* deps: negotiator@0.6.3
|
||||
|
||||
1.3.7 / 2019-04-29
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.6.2
|
||||
- Fix sorting charset, encoding, and language with extra parameters
|
||||
|
||||
1.3.6 / 2019-04-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.24
|
||||
- deps: mime-db@~1.40.0
|
||||
|
||||
1.3.5 / 2018-02-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.18
|
||||
- deps: mime-db@~1.33.0
|
||||
|
||||
1.3.4 / 2017-08-22
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.16
|
||||
- deps: mime-db@~1.29.0
|
||||
|
||||
1.3.3 / 2016-05-02
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.11
|
||||
- deps: mime-db@~1.23.0
|
||||
* deps: negotiator@0.6.1
|
||||
- perf: improve `Accept` parsing speed
|
||||
- perf: improve `Accept-Charset` parsing speed
|
||||
- perf: improve `Accept-Encoding` parsing speed
|
||||
- perf: improve `Accept-Language` parsing speed
|
||||
|
||||
1.3.2 / 2016-03-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.10
|
||||
- Fix extension of `application/dash+xml`
|
||||
- Update primary extension for `audio/mp4`
|
||||
- deps: mime-db@~1.22.0
|
||||
|
||||
1.3.1 / 2016-01-19
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.9
|
||||
- deps: mime-db@~1.21.0
|
||||
|
||||
1.3.0 / 2015-09-29
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.7
|
||||
- deps: mime-db@~1.19.0
|
||||
* deps: negotiator@0.6.0
|
||||
- Fix including type extensions in parameters in `Accept` parsing
|
||||
- Fix parsing `Accept` parameters with quoted equals
|
||||
- Fix parsing `Accept` parameters with quoted semicolons
|
||||
- Lazy-load modules from main entry point
|
||||
- perf: delay type concatenation until needed
|
||||
- perf: enable strict mode
|
||||
- perf: hoist regular expressions
|
||||
- perf: remove closures getting spec properties
|
||||
- perf: remove a closure from media type parsing
|
||||
- perf: remove property delete from media type parsing
|
||||
|
||||
1.2.13 / 2015-09-06
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.6
|
||||
- deps: mime-db@~1.18.0
|
||||
|
||||
1.2.12 / 2015-07-30
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.4
|
||||
- deps: mime-db@~1.16.0
|
||||
|
||||
1.2.11 / 2015-07-16
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.3
|
||||
- deps: mime-db@~1.15.0
|
||||
|
||||
1.2.10 / 2015-07-01
|
||||
===================
|
||||
|
||||
* deps: mime-types@~2.1.2
|
||||
- deps: mime-db@~1.14.0
|
||||
|
||||
1.2.9 / 2015-06-08
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.1
|
||||
- perf: fix deopt during mapping
|
||||
|
||||
1.2.8 / 2015-06-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.1.0
|
||||
- deps: mime-db@~1.13.0
|
||||
* perf: avoid argument reassignment & argument slice
|
||||
* perf: avoid negotiator recursive construction
|
||||
* perf: enable strict mode
|
||||
* perf: remove unnecessary bitwise operator
|
||||
|
||||
1.2.7 / 2015-05-10
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.3
|
||||
- Fix media type parameter matching to be case-insensitive
|
||||
|
||||
1.2.6 / 2015-05-07
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.11
|
||||
- deps: mime-db@~1.9.1
|
||||
* deps: negotiator@0.5.2
|
||||
- Fix comparing media types with quoted values
|
||||
- Fix splitting media types with quoted commas
|
||||
|
||||
1.2.5 / 2015-03-13
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.10
|
||||
- deps: mime-db@~1.8.0
|
||||
|
||||
1.2.4 / 2015-02-14
|
||||
==================
|
||||
|
||||
* Support Node.js 0.6
|
||||
* deps: mime-types@~2.0.9
|
||||
- deps: mime-db@~1.7.0
|
||||
* deps: negotiator@0.5.1
|
||||
- Fix preference sorting to be stable for long acceptable lists
|
||||
|
||||
1.2.3 / 2015-01-31
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.8
|
||||
- deps: mime-db@~1.6.0
|
||||
|
||||
1.2.2 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.7
|
||||
- deps: mime-db@~1.5.0
|
||||
|
||||
1.2.1 / 2014-12-30
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.5
|
||||
- deps: mime-db@~1.3.1
|
||||
|
||||
1.2.0 / 2014-12-19
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.5.0
|
||||
- Fix list return order when large accepted list
|
||||
- Fix missing identity encoding when q=0 exists
|
||||
- Remove dynamic building of Negotiator class
|
||||
|
||||
1.1.4 / 2014-12-10
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.4
|
||||
- deps: mime-db@~1.3.0
|
||||
|
||||
1.1.3 / 2014-11-09
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.3
|
||||
- deps: mime-db@~1.2.0
|
||||
|
||||
1.1.2 / 2014-10-14
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.9
|
||||
- Fix error when media type has invalid parameter
|
||||
|
||||
1.1.1 / 2014-09-28
|
||||
==================
|
||||
|
||||
* deps: mime-types@~2.0.2
|
||||
- deps: mime-db@~1.1.0
|
||||
* deps: negotiator@0.4.8
|
||||
- Fix all negotiations to be case-insensitive
|
||||
- Stable sort preferences of same quality according to client order
|
||||
|
||||
1.1.0 / 2014-09-02
|
||||
==================
|
||||
|
||||
* update `mime-types`
|
||||
|
||||
1.0.7 / 2014-07-04
|
||||
==================
|
||||
|
||||
* Fix wrong type returned from `type` when match after unknown extension
|
||||
|
||||
1.0.6 / 2014-06-24
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.7
|
||||
|
||||
1.0.5 / 2014-06-20
|
||||
==================
|
||||
|
||||
* fix crash when unknown extension given
|
||||
|
||||
1.0.4 / 2014-06-19
|
||||
==================
|
||||
|
||||
* use `mime-types`
|
||||
|
||||
1.0.3 / 2014-06-11
|
||||
==================
|
||||
|
||||
* deps: negotiator@0.4.6
|
||||
- Order by specificity when quality is the same
|
||||
|
||||
1.0.2 / 2014-05-29
|
||||
==================
|
||||
|
||||
* Fix interpretation when header not in request
|
||||
* deps: pin negotiator@0.4.5
|
||||
|
||||
1.0.1 / 2014-01-18
|
||||
==================
|
||||
|
||||
* Identity encoding isn't always acceptable
|
||||
* deps: negotiator@~0.4.0
|
||||
|
||||
1.0.0 / 2013-12-27
|
||||
==================
|
||||
|
||||
* Genesis
|
||||
23
labWeb/lab7/node_modules/accepts/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
140
labWeb/lab7/node_modules/accepts/README.md
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
# accepts
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||
[![Node.js Version][node-version-image]][node-version-url]
|
||||
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
|
||||
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
|
||||
|
||||
In addition to negotiator, it allows:
|
||||
|
||||
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
|
||||
as well as `('text/html', 'application/json')`.
|
||||
- Allows type shorthands such as `json`.
|
||||
- Returns `false` when no types match
|
||||
- Treats non-existent headers as `*`
|
||||
|
||||
## Installation
|
||||
|
||||
This is a [Node.js](https://nodejs.org/en/) module available through the
|
||||
[npm registry](https://www.npmjs.com/). Installation is done using the
|
||||
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
||||
|
||||
```sh
|
||||
$ npm install accepts
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
```
|
||||
|
||||
### accepts(req)
|
||||
|
||||
Create a new `Accepts` object for the given `req`.
|
||||
|
||||
#### .charset(charsets)
|
||||
|
||||
Return the first accepted charset. If nothing in `charsets` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .charsets()
|
||||
|
||||
Return the charsets that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .encoding(encodings)
|
||||
|
||||
Return the first accepted encoding. If nothing in `encodings` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .encodings()
|
||||
|
||||
Return the encodings that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .language(languages)
|
||||
|
||||
Return the first accepted language. If nothing in `languages` is accepted,
|
||||
then `false` is returned.
|
||||
|
||||
#### .languages()
|
||||
|
||||
Return the languages that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
#### .type(types)
|
||||
|
||||
Return the first accepted type (and it is returned as the same text as what
|
||||
appears in the `types` array). If nothing in `types` is accepted, then `false`
|
||||
is returned.
|
||||
|
||||
The `types` array can contain full MIME types or file extensions. Any value
|
||||
that is not a full MIME types is passed to `require('mime-types').lookup`.
|
||||
|
||||
#### .types()
|
||||
|
||||
Return the types that the request accepts, in the order of the client's
|
||||
preference (most preferred first).
|
||||
|
||||
## Examples
|
||||
|
||||
### Simple type negotiation
|
||||
|
||||
This simple example shows how to use `accepts` to return a different typed
|
||||
respond body based on what the client wants to accept. The server lists it's
|
||||
preferences in order and will get back the best match between the client and
|
||||
server.
|
||||
|
||||
```js
|
||||
var accepts = require('accepts')
|
||||
var http = require('http')
|
||||
|
||||
function app (req, res) {
|
||||
var accept = accepts(req)
|
||||
|
||||
// the order of this list is significant; should be server preferred order
|
||||
switch (accept.type(['json', 'html'])) {
|
||||
case 'json':
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.write('{"hello":"world!"}')
|
||||
break
|
||||
case 'html':
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.write('<b>hello, world!</b>')
|
||||
break
|
||||
default:
|
||||
// the fallback is text/plain, so no need to specify it above
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.write('hello, world!')
|
||||
break
|
||||
}
|
||||
|
||||
res.end()
|
||||
}
|
||||
|
||||
http.createServer(app).listen(3000)
|
||||
```
|
||||
|
||||
You can test this out with the cURL program:
|
||||
```sh
|
||||
curl -I -H'Accept: text/html' http://localhost:3000/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
|
||||
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
|
||||
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
|
||||
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
|
||||
[node-version-image]: https://badgen.net/npm/node/accepts
|
||||
[node-version-url]: https://nodejs.org/en/download
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
|
||||
[npm-url]: https://npmjs.org/package/accepts
|
||||
[npm-version-image]: https://badgen.net/npm/v/accepts
|
||||
238
labWeb/lab7/node_modules/accepts/index.js
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*!
|
||||
* accepts
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var Negotiator = require('negotiator')
|
||||
var mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @public
|
||||
*/
|
||||
|
||||
module.exports = Accepts
|
||||
|
||||
/**
|
||||
* Create a new Accepts object for the given req.
|
||||
*
|
||||
* @param {object} req
|
||||
* @public
|
||||
*/
|
||||
|
||||
function Accepts (req) {
|
||||
if (!(this instanceof Accepts)) {
|
||||
return new Accepts(req)
|
||||
}
|
||||
|
||||
this.headers = req.headers
|
||||
this.negotiator = new Negotiator(req)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `undefined`, in which
|
||||
* case you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* The `type` value may be a single mime type string
|
||||
* such as "application/json", the extension name
|
||||
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // Accept: text/html
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('html');
|
||||
* // => "html"
|
||||
* this.types('text/html');
|
||||
* // => "text/html"
|
||||
* this.types('json', 'text');
|
||||
* // => "json"
|
||||
* this.types('application/json');
|
||||
* // => "application/json"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* this.types('image/png');
|
||||
* this.types('png');
|
||||
* // => undefined
|
||||
*
|
||||
* // Accept: text/*;q=.5, application/json
|
||||
* this.types(['html', 'json']);
|
||||
* this.types('html', 'json');
|
||||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} types...
|
||||
* @return {String|Array|Boolean}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.type =
|
||||
Accepts.prototype.types = function (types_) {
|
||||
var types = types_
|
||||
|
||||
// support flattened arguments
|
||||
if (types && !Array.isArray(types)) {
|
||||
types = new Array(arguments.length)
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
types[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no types, return all requested types
|
||||
if (!types || types.length === 0) {
|
||||
return this.negotiator.mediaTypes()
|
||||
}
|
||||
|
||||
// no accept header, return first given type
|
||||
if (!this.headers.accept) {
|
||||
return types[0]
|
||||
}
|
||||
|
||||
var mimes = types.map(extToMime)
|
||||
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
|
||||
var first = accepts[0]
|
||||
|
||||
return first
|
||||
? types[mimes.indexOf(first)]
|
||||
: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted encodings or best fit based on `encodings`.
|
||||
*
|
||||
* Given `Accept-Encoding: gzip, deflate`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['gzip', 'deflate']
|
||||
*
|
||||
* @param {String|Array} encodings...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.encoding =
|
||||
Accepts.prototype.encodings = function (encodings_) {
|
||||
var encodings = encodings_
|
||||
|
||||
// support flattened arguments
|
||||
if (encodings && !Array.isArray(encodings)) {
|
||||
encodings = new Array(arguments.length)
|
||||
for (var i = 0; i < encodings.length; i++) {
|
||||
encodings[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no encodings, return all requested encodings
|
||||
if (!encodings || encodings.length === 0) {
|
||||
return this.negotiator.encodings()
|
||||
}
|
||||
|
||||
return this.negotiator.encodings(encodings)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted charsets or best fit based on `charsets`.
|
||||
*
|
||||
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['utf-8', 'utf-7', 'iso-8859-1']
|
||||
*
|
||||
* @param {String|Array} charsets...
|
||||
* @return {String|Array}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.charset =
|
||||
Accepts.prototype.charsets = function (charsets_) {
|
||||
var charsets = charsets_
|
||||
|
||||
// support flattened arguments
|
||||
if (charsets && !Array.isArray(charsets)) {
|
||||
charsets = new Array(arguments.length)
|
||||
for (var i = 0; i < charsets.length; i++) {
|
||||
charsets[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no charsets, return all requested charsets
|
||||
if (!charsets || charsets.length === 0) {
|
||||
return this.negotiator.charsets()
|
||||
}
|
||||
|
||||
return this.negotiator.charsets(charsets)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accepted languages or best fit based on `langs`.
|
||||
*
|
||||
* Given `Accept-Language: en;q=0.8, es, pt`
|
||||
* an array sorted by quality is returned:
|
||||
*
|
||||
* ['es', 'pt', 'en']
|
||||
*
|
||||
* @param {String|Array} langs...
|
||||
* @return {Array|String}
|
||||
* @public
|
||||
*/
|
||||
|
||||
Accepts.prototype.lang =
|
||||
Accepts.prototype.langs =
|
||||
Accepts.prototype.language =
|
||||
Accepts.prototype.languages = function (languages_) {
|
||||
var languages = languages_
|
||||
|
||||
// support flattened arguments
|
||||
if (languages && !Array.isArray(languages)) {
|
||||
languages = new Array(arguments.length)
|
||||
for (var i = 0; i < languages.length; i++) {
|
||||
languages[i] = arguments[i]
|
||||
}
|
||||
}
|
||||
|
||||
// no languages, return all requested languages
|
||||
if (!languages || languages.length === 0) {
|
||||
return this.negotiator.languages()
|
||||
}
|
||||
|
||||
return this.negotiator.languages(languages)[0] || false
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert extnames to mime.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function extToMime (type) {
|
||||
return type.indexOf('/') === -1
|
||||
? mime.lookup(type)
|
||||
: type
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if mime is valid.
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function validMime (type) {
|
||||
return typeof type === 'string'
|
||||
}
|
||||
47
labWeb/lab7/node_modules/accepts/package.json
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "accepts",
|
||||
"description": "Higher-level content negotiation",
|
||||
"version": "1.3.8",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "jshttp/accepts",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"deep-equal": "1.0.1",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-standard": "14.1.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-markdown": "2.2.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "4.3.1",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"mocha": "9.2.0",
|
||||
"nyc": "15.1.0"
|
||||
},
|
||||
"files": [
|
||||
"LICENSE",
|
||||
"HISTORY.md",
|
||||
"index.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test"
|
||||
},
|
||||
"keywords": [
|
||||
"content",
|
||||
"negotiation",
|
||||
"accept",
|
||||
"accepts"
|
||||
]
|
||||
}
|
||||
15
labWeb/lab7/node_modules/anymatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
87
labWeb/lab7/node_modules/anymatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
anymatch [](https://travis-ci.org/micromatch/anymatch) [](https://coveralls.io/r/micromatch/anymatch?branch=master)
|
||||
======
|
||||
Javascript module to match a string against a regular expression, glob, string,
|
||||
or function that takes the string as an argument and returns a truthy or falsy
|
||||
value. The matcher can also be an array of any or all of these. Useful for
|
||||
allowing a very flexible user-defined config to define things like file paths.
|
||||
|
||||
__Note: This module has Bash-parity, please be aware that Windows-style backslashes are not supported as separators. See https://github.com/micromatch/micromatch#backslashes for more information.__
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
```sh
|
||||
npm install anymatch
|
||||
```
|
||||
|
||||
#### anymatch(matchers, testString, [returnIndex], [options])
|
||||
* __matchers__: (_Array|String|RegExp|Function_)
|
||||
String to be directly matched, string with glob patterns, regular expression
|
||||
test, function that takes the testString as an argument and returns a truthy
|
||||
value if it should be matched, or an array of any number and mix of these types.
|
||||
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||
passed as an array, the first element of the array will be used as the
|
||||
`testString` for non-function matchers, while the entire array will be applied
|
||||
as the arguments for function matchers.
|
||||
* __options__: (_Object_ [optional]_) Any of the [picomatch](https://github.com/micromatch/picomatch#options) options.
|
||||
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||
boolean result.
|
||||
|
||||
```js
|
||||
const anymatch = require('anymatch');
|
||||
|
||||
const matchers = [ 'path/to/file.js', 'path/anyjs/**/*.js', /foo.js$/, string => string.includes('bar') && string.length > 10 ] ;
|
||||
|
||||
anymatch(matchers, 'path/to/file.js'); // true
|
||||
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||
anymatch(matchers, 'path/to/foo.js'); // true
|
||||
anymatch(matchers, 'path/to/bar.js'); // true
|
||||
anymatch(matchers, 'bar.js'); // false
|
||||
|
||||
// returnIndex = true
|
||||
anymatch(matchers, 'foo.js', {returnIndex: true}); // 2
|
||||
anymatch(matchers, 'path/anyjs/foo.js', {returnIndex: true}); // 1
|
||||
|
||||
// any picomatc
|
||||
|
||||
// using globs to match directories and their children
|
||||
anymatch('node_modules', 'node_modules'); // true
|
||||
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
|
||||
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
|
||||
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
|
||||
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
|
||||
|
||||
const matcher = anymatch(matchers);
|
||||
['foo.js', 'bar.js'].filter(matcher); // [ 'foo.js' ]
|
||||
anymatch master* ❯
|
||||
|
||||
```
|
||||
|
||||
#### anymatch(matchers)
|
||||
You can also pass in only your matcher(s) to get a curried function that has
|
||||
already been bound to the provided matching criteria. This can be used as an
|
||||
`Array#filter` callback.
|
||||
|
||||
```js
|
||||
var matcher = anymatch(matchers);
|
||||
|
||||
matcher('path/to/file.js'); // true
|
||||
matcher('path/anyjs/baz.js', true); // 1
|
||||
|
||||
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||
```
|
||||
|
||||
Changelog
|
||||
----------
|
||||
[See release notes page on GitHub](https://github.com/micromatch/anymatch/releases)
|
||||
|
||||
- **v3.0:** Removed `startIndex` and `endIndex` arguments. Node 8.x-only.
|
||||
- **v2.0:** [micromatch](https://github.com/jonschlinkert/micromatch) moves away from minimatch-parity and inline with Bash. This includes handling backslashes differently (see https://github.com/micromatch/micromatch#backslashes for more information).
|
||||
- **v1.2:** anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||
for glob pattern matching. Issues with glob pattern matching should be
|
||||
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||
|
||||
License
|
||||
-------
|
||||
[ISC](https://raw.github.com/micromatch/anymatch/master/LICENSE)
|
||||
20
labWeb/lab7/node_modules/anymatch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
type AnymatchFn = (testString: string) => boolean;
|
||||
type AnymatchPattern = string|RegExp|AnymatchFn;
|
||||
type AnymatchMatcher = AnymatchPattern|AnymatchPattern[]
|
||||
type AnymatchTester = {
|
||||
(testString: string|any[], returnIndex: true): number;
|
||||
(testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
type PicomatchOptions = {dot: boolean};
|
||||
|
||||
declare const anymatch: {
|
||||
(matchers: AnymatchMatcher): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: null, returnIndex: true | PicomatchOptions): AnymatchTester;
|
||||
(matchers: AnymatchMatcher, testString: string|any[], returnIndex: true | PicomatchOptions): number;
|
||||
(matchers: AnymatchMatcher, testString: string|any[]): boolean;
|
||||
}
|
||||
|
||||
export {AnymatchMatcher as Matcher}
|
||||
export {AnymatchTester as Tester}
|
||||
export default anymatch
|
||||
104
labWeb/lab7/node_modules/anymatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const picomatch = require('picomatch');
|
||||
const normalizePath = require('normalize-path');
|
||||
|
||||
/**
|
||||
* @typedef {(testString: string) => boolean} AnymatchFn
|
||||
* @typedef {string|RegExp|AnymatchFn} AnymatchPattern
|
||||
* @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
|
||||
*/
|
||||
const BANG = '!';
|
||||
const DEFAULT_OPTIONS = {returnIndex: false};
|
||||
const arrify = (item) => Array.isArray(item) ? item : [item];
|
||||
|
||||
/**
|
||||
* @param {AnymatchPattern} matcher
|
||||
* @param {object} options
|
||||
* @returns {AnymatchFn}
|
||||
*/
|
||||
const createPattern = (matcher, options) => {
|
||||
if (typeof matcher === 'function') {
|
||||
return matcher;
|
||||
}
|
||||
if (typeof matcher === 'string') {
|
||||
const glob = picomatch(matcher, options);
|
||||
return (string) => matcher === string || glob(string);
|
||||
}
|
||||
if (matcher instanceof RegExp) {
|
||||
return (string) => matcher.test(string);
|
||||
}
|
||||
return (string) => false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<Function>} patterns
|
||||
* @param {Array<Function>} negPatterns
|
||||
* @param {String|Array} args
|
||||
* @param {Boolean} returnIndex
|
||||
* @returns {boolean|number}
|
||||
*/
|
||||
const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
|
||||
const isList = Array.isArray(args);
|
||||
const _path = isList ? args[0] : args;
|
||||
if (!isList && typeof _path !== 'string') {
|
||||
throw new TypeError('anymatch: second argument must be a string: got ' +
|
||||
Object.prototype.toString.call(_path))
|
||||
}
|
||||
const path = normalizePath(_path, false);
|
||||
|
||||
for (let index = 0; index < negPatterns.length; index++) {
|
||||
const nglob = negPatterns[index];
|
||||
if (nglob(path)) {
|
||||
return returnIndex ? -1 : false;
|
||||
}
|
||||
}
|
||||
|
||||
const applied = isList && [path].concat(args.slice(1));
|
||||
for (let index = 0; index < patterns.length; index++) {
|
||||
const pattern = patterns[index];
|
||||
if (isList ? pattern(...applied) : pattern(path)) {
|
||||
return returnIndex ? index : true;
|
||||
}
|
||||
}
|
||||
|
||||
return returnIndex ? -1 : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {AnymatchMatcher} matchers
|
||||
* @param {Array|string} testString
|
||||
* @param {object} options
|
||||
* @returns {boolean|number|Function}
|
||||
*/
|
||||
const anymatch = (matchers, testString, options = DEFAULT_OPTIONS) => {
|
||||
if (matchers == null) {
|
||||
throw new TypeError('anymatch: specify first argument');
|
||||
}
|
||||
const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
|
||||
const returnIndex = opts.returnIndex || false;
|
||||
|
||||
// Early cache for matchers.
|
||||
const mtchers = arrify(matchers);
|
||||
const negatedGlobs = mtchers
|
||||
.filter(item => typeof item === 'string' && item.charAt(0) === BANG)
|
||||
.map(item => item.slice(1))
|
||||
.map(item => picomatch(item, opts));
|
||||
const patterns = mtchers
|
||||
.filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
|
||||
.map(matcher => createPattern(matcher, opts));
|
||||
|
||||
if (testString == null) {
|
||||
return (testString, ri = false) => {
|
||||
const returnIndex = typeof ri === 'boolean' ? ri : false;
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
|
||||
};
|
||||
|
||||
anymatch.default = anymatch;
|
||||
module.exports = anymatch;
|
||||
48
labWeb/lab7/node_modules/anymatch/package.json
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "anymatch",
|
||||
"version": "3.1.3",
|
||||
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "Elan Shanker",
|
||||
"url": "https://github.com/es128"
|
||||
},
|
||||
"license": "ISC",
|
||||
"homepage": "https://github.com/micromatch/anymatch",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/micromatch/anymatch"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"any",
|
||||
"string",
|
||||
"file",
|
||||
"fs",
|
||||
"list",
|
||||
"glob",
|
||||
"regex",
|
||||
"regexp",
|
||||
"regular",
|
||||
"expression",
|
||||
"function"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "nyc mocha",
|
||||
"mocha": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^6.1.3",
|
||||
"nyc": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
}
|
||||
21
labWeb/lab7/node_modules/array-flatten/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
43
labWeb/lab7/node_modules/array-flatten/README.md
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Array Flatten
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![NPM downloads][downloads-image]][downloads-url]
|
||||
[![Build status][travis-image]][travis-url]
|
||||
[![Test coverage][coveralls-image]][coveralls-url]
|
||||
|
||||
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install array-flatten --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var flatten = require('array-flatten')
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
|
||||
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
|
||||
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
|
||||
|
||||
(function () {
|
||||
flatten(arguments) //=> [1, 2, 3]
|
||||
})(1, [2, 3])
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
|
||||
[npm-url]: https://npmjs.org/package/array-flatten
|
||||
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
|
||||
[downloads-url]: https://npmjs.org/package/array-flatten
|
||||
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
|
||||
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
|
||||
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
|
||||
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master
|
||||
64
labWeb/lab7/node_modules/array-flatten/array-flatten.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Expose `arrayFlatten`.
|
||||
*/
|
||||
module.exports = arrayFlatten
|
||||
|
||||
/**
|
||||
* Recursive flatten function with depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenWithDepth (array, result, depth) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (depth > 0 && Array.isArray(value)) {
|
||||
flattenWithDepth(value, result, depth - 1)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive flatten function. Omitting depth is slightly faster.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Array} result
|
||||
* @return {Array}
|
||||
*/
|
||||
function flattenForever (array, result) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
var value = array[i]
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
flattenForever(value, result)
|
||||
} else {
|
||||
result.push(value)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an array, with the ability to define a depth.
|
||||
*
|
||||
* @param {Array} array
|
||||
* @param {Number} depth
|
||||
* @return {Array}
|
||||
*/
|
||||
function arrayFlatten (array, depth) {
|
||||
if (depth == null) {
|
||||
return flattenForever(array, [])
|
||||
}
|
||||
|
||||
return flattenWithDepth(array, [], depth)
|
||||
}
|
||||
39
labWeb/lab7/node_modules/array-flatten/package.json
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "array-flatten",
|
||||
"version": "1.1.1",
|
||||
"description": "Flatten an array of nested arrays into a single flat array",
|
||||
"main": "array-flatten.js",
|
||||
"files": [
|
||||
"array-flatten.js",
|
||||
"LICENSE"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "istanbul cover _mocha -- -R spec"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/blakeembrey/array-flatten.git"
|
||||
},
|
||||
"keywords": [
|
||||
"array",
|
||||
"flatten",
|
||||
"arguments",
|
||||
"depth"
|
||||
],
|
||||
"author": {
|
||||
"name": "Blake Embrey",
|
||||
"email": "hello@blakeembrey.com",
|
||||
"url": "http://blakeembrey.me"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/blakeembrey/array-flatten/issues"
|
||||
},
|
||||
"homepage": "https://github.com/blakeembrey/array-flatten",
|
||||
"devDependencies": {
|
||||
"istanbul": "^0.3.13",
|
||||
"mocha": "^2.2.4",
|
||||
"pre-commit": "^1.0.7",
|
||||
"standard": "^3.7.3"
|
||||
}
|
||||
}
|
||||
23
labWeb/lab7/node_modules/balanced-match/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(MIT)
|
||||
|
||||
Original code Copyright Julian Gruber <julian@juliangruber.com>
|
||||
|
||||
Port to TypeScript Copyright Isaac Z. Schlueter <i@izs.me>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
57
labWeb/lab7/node_modules/balanced-match/README.md
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# balanced-match
|
||||
|
||||
Match balanced string pairs, like `{` and `}` or `<b>` and
|
||||
`</b>`. Supports regular expressions as well!
|
||||
|
||||
## Example
|
||||
|
||||
Get the first matching pair of braces:
|
||||
|
||||
```js
|
||||
import { balanced } from 'balanced-match'
|
||||
|
||||
console.log(balanced('{', '}', 'pre{in{nested}}post'))
|
||||
console.log(balanced('{', '}', 'pre{first}between{second}post'))
|
||||
console.log(
|
||||
balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'),
|
||||
)
|
||||
```
|
||||
|
||||
The matches are:
|
||||
|
||||
```bash
|
||||
$ node example.js
|
||||
{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
|
||||
{ start: 3,
|
||||
end: 9,
|
||||
pre: 'pre',
|
||||
body: 'first',
|
||||
post: 'between{second}post' }
|
||||
{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### const m = balanced(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
object with those keys:
|
||||
|
||||
- **start** the index of the first match of `a`
|
||||
- **end** the index of the matching `b`
|
||||
- **pre** the preamble, `a` and `b` not included
|
||||
- **body** the match, `a` and `b` not included
|
||||
- **post** the postscript, `a` and `b` not included
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
|
||||
|
||||
### const r = balanced.range(a, b, str)
|
||||
|
||||
For the first non-nested matching pair of `a` and `b` in `str`, return an
|
||||
array with indexes: `[ <a index>, <b index> ]`.
|
||||
|
||||
If there's no match, `undefined` will be returned.
|
||||
|
||||
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
|
||||
9
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export declare const balanced: (a: string | RegExp, b: string | RegExp, str: string) => false | {
|
||||
start: number;
|
||||
end: number;
|
||||
pre: string;
|
||||
body: string;
|
||||
post: string;
|
||||
} | undefined;
|
||||
export declare const range: (a: string, b: string, str: string) => undefined | [number, number];
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,GAAG,MAAM,EAClB,GAAG,MAAM,GAAG,MAAM,EAClB,KAAK,MAAM;;;;;;aAgBZ,CAAA;AAOD,eAAO,MAAM,KAAK,GAChB,GAAG,MAAM,EACT,GAAG,MAAM,EACT,KAAK,MAAM,KACV,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CA2C7B,CAAA"}
|
||||
59
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.range = exports.balanced = void 0;
|
||||
const balanced = (a, b, str) => {
|
||||
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
||||
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
||||
const r = ma !== null && mb != null && (0, exports.range)(ma, mb, str);
|
||||
return (r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0] + ma.length, r[1]),
|
||||
post: str.slice(r[1] + mb.length),
|
||||
});
|
||||
};
|
||||
exports.balanced = balanced;
|
||||
const maybeMatch = (reg, str) => {
|
||||
const m = str.match(reg);
|
||||
return m ? m[0] : null;
|
||||
};
|
||||
const range = (a, b, str) => {
|
||||
let begs, beg, left, right = undefined, result;
|
||||
let ai = str.indexOf(a);
|
||||
let bi = str.indexOf(b, ai + 1);
|
||||
let i = ai;
|
||||
if (ai >= 0 && bi > 0) {
|
||||
if (a === b) {
|
||||
return [ai, bi];
|
||||
}
|
||||
begs = [];
|
||||
left = str.length;
|
||||
while (i >= 0 && !result) {
|
||||
if (i === ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
}
|
||||
else if (begs.length === 1) {
|
||||
const r = begs.pop();
|
||||
if (r !== undefined)
|
||||
result = [r, bi];
|
||||
}
|
||||
else {
|
||||
beg = begs.pop();
|
||||
if (beg !== undefined && beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
if (begs.length && right !== undefined) {
|
||||
result = [left, right];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
exports.range = range;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/commonjs/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ,GAAG,CACtB,CAAkB,EAClB,CAAkB,EAClB,GAAW,EACX,EAAE;IACF,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvD,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvD,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,IAAA,aAAK,EAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IAEzD,OAAO,CACL,CAAC,IAAI;QACH,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACX,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACT,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;KAClC,CACF,CAAA;AACH,CAAC,CAAA;AAnBY,QAAA,QAAQ,YAmBpB;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACxB,CAAC,CAAA;AAEM,MAAM,KAAK,GAAG,CACnB,CAAS,EACT,CAAS,EACT,GAAW,EACmB,EAAE;IAChC,IAAI,IAAc,EAChB,GAAuB,EACvB,IAAY,EACZ,KAAK,GAAuB,SAAS,EACrC,MAAoC,CAAA;IACtC,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACvB,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAA;IAEV,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,GAAG,EAAE,CAAA;QACT,IAAI,GAAG,GAAG,CAAC,MAAM,CAAA;QAEjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACZ,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACpB,IAAI,CAAC,KAAK,SAAS;oBAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACvC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAChB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;oBACpC,IAAI,GAAG,GAAG,CAAA;oBACV,KAAK,GAAG,EAAE,CAAA;gBACZ,CAAC;gBAED,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;YAED,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AA/CY,QAAA,KAAK,SA+CjB","sourcesContent":["export const balanced = (\n a: string | RegExp,\n b: string | RegExp,\n str: string,\n) => {\n const ma = a instanceof RegExp ? maybeMatch(a, str) : a\n const mb = b instanceof RegExp ? maybeMatch(b, str) : b\n\n const r = ma !== null && mb != null && range(ma, mb, str)\n\n return (\n r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + ma.length, r[1]),\n post: str.slice(r[1] + mb.length),\n }\n )\n}\n\nconst maybeMatch = (reg: RegExp, str: string) => {\n const m = str.match(reg)\n return m ? m[0] : null\n}\n\nexport const range = (\n a: string,\n b: string,\n str: string,\n): undefined | [number, number] => {\n let begs: number[],\n beg: number | undefined,\n left: number,\n right: number | undefined = undefined,\n result: undefined | [number, number]\n let ai = str.indexOf(a)\n let bi = str.indexOf(b, ai + 1)\n let i = ai\n\n if (ai >= 0 && bi > 0) {\n if (a === b) {\n return [ai, bi]\n }\n begs = []\n left = str.length\n\n while (i >= 0 && !result) {\n if (i === ai) {\n begs.push(i)\n ai = str.indexOf(a, i + 1)\n } else if (begs.length === 1) {\n const r = begs.pop()\n if (r !== undefined) result = [r, bi]\n } else {\n beg = begs.pop()\n if (beg !== undefined && beg < left) {\n left = beg\n right = bi\n }\n\n bi = str.indexOf(b, i + 1)\n }\n\n i = ai < bi && ai >= 0 ? ai : bi\n }\n\n if (begs.length && right !== undefined) {\n result = [left, right]\n }\n }\n\n return result\n}\n"]}
|
||||
3
labWeb/lab7/node_modules/balanced-match/dist/commonjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
9
labWeb/lab7/node_modules/balanced-match/dist/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export declare const balanced: (a: string | RegExp, b: string | RegExp, str: string) => false | {
|
||||
start: number;
|
||||
end: number;
|
||||
pre: string;
|
||||
body: string;
|
||||
post: string;
|
||||
} | undefined;
|
||||
export declare const range: (a: string, b: string, str: string) => undefined | [number, number];
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/esm/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,GACnB,GAAG,MAAM,GAAG,MAAM,EAClB,GAAG,MAAM,GAAG,MAAM,EAClB,KAAK,MAAM;;;;;;aAgBZ,CAAA;AAOD,eAAO,MAAM,KAAK,GAChB,GAAG,MAAM,EACT,GAAG,MAAM,EACT,KAAK,MAAM,KACV,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CA2C7B,CAAA"}
|
||||
54
labWeb/lab7/node_modules/balanced-match/dist/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
export const balanced = (a, b, str) => {
|
||||
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
||||
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
||||
const r = ma !== null && mb != null && range(ma, mb, str);
|
||||
return (r && {
|
||||
start: r[0],
|
||||
end: r[1],
|
||||
pre: str.slice(0, r[0]),
|
||||
body: str.slice(r[0] + ma.length, r[1]),
|
||||
post: str.slice(r[1] + mb.length),
|
||||
});
|
||||
};
|
||||
const maybeMatch = (reg, str) => {
|
||||
const m = str.match(reg);
|
||||
return m ? m[0] : null;
|
||||
};
|
||||
export const range = (a, b, str) => {
|
||||
let begs, beg, left, right = undefined, result;
|
||||
let ai = str.indexOf(a);
|
||||
let bi = str.indexOf(b, ai + 1);
|
||||
let i = ai;
|
||||
if (ai >= 0 && bi > 0) {
|
||||
if (a === b) {
|
||||
return [ai, bi];
|
||||
}
|
||||
begs = [];
|
||||
left = str.length;
|
||||
while (i >= 0 && !result) {
|
||||
if (i === ai) {
|
||||
begs.push(i);
|
||||
ai = str.indexOf(a, i + 1);
|
||||
}
|
||||
else if (begs.length === 1) {
|
||||
const r = begs.pop();
|
||||
if (r !== undefined)
|
||||
result = [r, bi];
|
||||
}
|
||||
else {
|
||||
beg = begs.pop();
|
||||
if (beg !== undefined && beg < left) {
|
||||
left = beg;
|
||||
right = bi;
|
||||
}
|
||||
bi = str.indexOf(b, i + 1);
|
||||
}
|
||||
i = ai < bi && ai >= 0 ? ai : bi;
|
||||
}
|
||||
if (begs.length && right !== undefined) {
|
||||
result = [left, right];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
labWeb/lab7/node_modules/balanced-match/dist/esm/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,CAAkB,EAClB,CAAkB,EAClB,GAAW,EACX,EAAE;IACF,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACvD,MAAM,EAAE,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEvD,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IAEzD,OAAO,CACL,CAAC,IAAI;QACH,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACX,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACT,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;KAClC,CACF,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE;IAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACxB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,CAAS,EACT,CAAS,EACT,GAAW,EACmB,EAAE;IAChC,IAAI,IAAc,EAChB,GAAuB,EACvB,IAAY,EACZ,KAAK,GAAuB,SAAS,EACrC,MAAoC,CAAA;IACtC,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACvB,IAAI,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAA;IAEV,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACZ,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,GAAG,EAAE,CAAA;QACT,IAAI,GAAG,GAAG,CAAC,MAAM,CAAA;QAEjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACZ,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBACpB,IAAI,CAAC,KAAK,SAAS;oBAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACvC,CAAC;iBAAM,CAAC;gBACN,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;gBAChB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,EAAE,CAAC;oBACpC,IAAI,GAAG,GAAG,CAAA;oBACV,KAAK,GAAG,EAAE,CAAA;gBACZ,CAAC;gBAED,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC5B,CAAC;YAED,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACvC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA","sourcesContent":["export const balanced = (\n a: string | RegExp,\n b: string | RegExp,\n str: string,\n) => {\n const ma = a instanceof RegExp ? maybeMatch(a, str) : a\n const mb = b instanceof RegExp ? maybeMatch(b, str) : b\n\n const r = ma !== null && mb != null && range(ma, mb, str)\n\n return (\n r && {\n start: r[0],\n end: r[1],\n pre: str.slice(0, r[0]),\n body: str.slice(r[0] + ma.length, r[1]),\n post: str.slice(r[1] + mb.length),\n }\n )\n}\n\nconst maybeMatch = (reg: RegExp, str: string) => {\n const m = str.match(reg)\n return m ? m[0] : null\n}\n\nexport const range = (\n a: string,\n b: string,\n str: string,\n): undefined | [number, number] => {\n let begs: number[],\n beg: number | undefined,\n left: number,\n right: number | undefined = undefined,\n result: undefined | [number, number]\n let ai = str.indexOf(a)\n let bi = str.indexOf(b, ai + 1)\n let i = ai\n\n if (ai >= 0 && bi > 0) {\n if (a === b) {\n return [ai, bi]\n }\n begs = []\n left = str.length\n\n while (i >= 0 && !result) {\n if (i === ai) {\n begs.push(i)\n ai = str.indexOf(a, i + 1)\n } else if (begs.length === 1) {\n const r = begs.pop()\n if (r !== undefined) result = [r, bi]\n } else {\n beg = begs.pop()\n if (beg !== undefined && beg < left) {\n left = beg\n right = bi\n }\n\n bi = str.indexOf(b, i + 1)\n }\n\n i = ai < bi && ai >= 0 ? ai : bi\n }\n\n if (begs.length && right !== undefined) {\n result = [left, right]\n }\n }\n\n return result\n}\n"]}
|
||||
3
labWeb/lab7/node_modules/balanced-match/dist/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
68
labWeb/lab7/node_modules/balanced-match/package.json
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "balanced-match",
|
||||
"description": "Match balanced character pairs, like \"{\" and \"}\"",
|
||||
"version": "4.0.4",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/balanced-match.git"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"prepublishOnly": "git push origin --follow-tags",
|
||||
"prepare": "tshy",
|
||||
"pretest": "npm run prepare",
|
||||
"presnap": "npm run prepare",
|
||||
"test": "tap",
|
||||
"snap": "tap",
|
||||
"format": "prettier --write .",
|
||||
"benchmark": "node benchmark/index.js",
|
||||
"typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/brace-expansion": "^1.1.2",
|
||||
"@types/node": "^25.2.1",
|
||||
"mkdirp": "^3.0.1",
|
||||
"prettier": "^3.3.2",
|
||||
"tap": "^21.6.2",
|
||||
"tshy": "^3.0.2",
|
||||
"typedoc": "^0.28.5"
|
||||
},
|
||||
"keywords": [
|
||||
"match",
|
||||
"regexp",
|
||||
"test",
|
||||
"balanced",
|
||||
"parse"
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"tshy": {
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
},
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"module": "./dist/esm/index.js"
|
||||
}
|
||||
260
labWeb/lab7/node_modules/binary-extensions/binary-extensions.json
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
[
|
||||
"3dm",
|
||||
"3ds",
|
||||
"3g2",
|
||||
"3gp",
|
||||
"7z",
|
||||
"a",
|
||||
"aac",
|
||||
"adp",
|
||||
"ai",
|
||||
"aif",
|
||||
"aiff",
|
||||
"alz",
|
||||
"ape",
|
||||
"apk",
|
||||
"appimage",
|
||||
"ar",
|
||||
"arj",
|
||||
"asf",
|
||||
"au",
|
||||
"avi",
|
||||
"bak",
|
||||
"baml",
|
||||
"bh",
|
||||
"bin",
|
||||
"bk",
|
||||
"bmp",
|
||||
"btif",
|
||||
"bz2",
|
||||
"bzip2",
|
||||
"cab",
|
||||
"caf",
|
||||
"cgm",
|
||||
"class",
|
||||
"cmx",
|
||||
"cpio",
|
||||
"cr2",
|
||||
"cur",
|
||||
"dat",
|
||||
"dcm",
|
||||
"deb",
|
||||
"dex",
|
||||
"djvu",
|
||||
"dll",
|
||||
"dmg",
|
||||
"dng",
|
||||
"doc",
|
||||
"docm",
|
||||
"docx",
|
||||
"dot",
|
||||
"dotm",
|
||||
"dra",
|
||||
"DS_Store",
|
||||
"dsk",
|
||||
"dts",
|
||||
"dtshd",
|
||||
"dvb",
|
||||
"dwg",
|
||||
"dxf",
|
||||
"ecelp4800",
|
||||
"ecelp7470",
|
||||
"ecelp9600",
|
||||
"egg",
|
||||
"eol",
|
||||
"eot",
|
||||
"epub",
|
||||
"exe",
|
||||
"f4v",
|
||||
"fbs",
|
||||
"fh",
|
||||
"fla",
|
||||
"flac",
|
||||
"flatpak",
|
||||
"fli",
|
||||
"flv",
|
||||
"fpx",
|
||||
"fst",
|
||||
"fvt",
|
||||
"g3",
|
||||
"gh",
|
||||
"gif",
|
||||
"graffle",
|
||||
"gz",
|
||||
"gzip",
|
||||
"h261",
|
||||
"h263",
|
||||
"h264",
|
||||
"icns",
|
||||
"ico",
|
||||
"ief",
|
||||
"img",
|
||||
"ipa",
|
||||
"iso",
|
||||
"jar",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"jpgv",
|
||||
"jpm",
|
||||
"jxr",
|
||||
"key",
|
||||
"ktx",
|
||||
"lha",
|
||||
"lib",
|
||||
"lvp",
|
||||
"lz",
|
||||
"lzh",
|
||||
"lzma",
|
||||
"lzo",
|
||||
"m3u",
|
||||
"m4a",
|
||||
"m4v",
|
||||
"mar",
|
||||
"mdi",
|
||||
"mht",
|
||||
"mid",
|
||||
"midi",
|
||||
"mj2",
|
||||
"mka",
|
||||
"mkv",
|
||||
"mmr",
|
||||
"mng",
|
||||
"mobi",
|
||||
"mov",
|
||||
"movie",
|
||||
"mp3",
|
||||
"mp4",
|
||||
"mp4a",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"mpga",
|
||||
"mxu",
|
||||
"nef",
|
||||
"npx",
|
||||
"numbers",
|
||||
"nupkg",
|
||||
"o",
|
||||
"odp",
|
||||
"ods",
|
||||
"odt",
|
||||
"oga",
|
||||
"ogg",
|
||||
"ogv",
|
||||
"otf",
|
||||
"ott",
|
||||
"pages",
|
||||
"pbm",
|
||||
"pcx",
|
||||
"pdb",
|
||||
"pdf",
|
||||
"pea",
|
||||
"pgm",
|
||||
"pic",
|
||||
"png",
|
||||
"pnm",
|
||||
"pot",
|
||||
"potm",
|
||||
"potx",
|
||||
"ppa",
|
||||
"ppam",
|
||||
"ppm",
|
||||
"pps",
|
||||
"ppsm",
|
||||
"ppsx",
|
||||
"ppt",
|
||||
"pptm",
|
||||
"pptx",
|
||||
"psd",
|
||||
"pya",
|
||||
"pyc",
|
||||
"pyo",
|
||||
"pyv",
|
||||
"qt",
|
||||
"rar",
|
||||
"ras",
|
||||
"raw",
|
||||
"resources",
|
||||
"rgb",
|
||||
"rip",
|
||||
"rlc",
|
||||
"rmf",
|
||||
"rmvb",
|
||||
"rpm",
|
||||
"rtf",
|
||||
"rz",
|
||||
"s3m",
|
||||
"s7z",
|
||||
"scpt",
|
||||
"sgi",
|
||||
"shar",
|
||||
"snap",
|
||||
"sil",
|
||||
"sketch",
|
||||
"slk",
|
||||
"smv",
|
||||
"snk",
|
||||
"so",
|
||||
"stl",
|
||||
"suo",
|
||||
"sub",
|
||||
"swf",
|
||||
"tar",
|
||||
"tbz",
|
||||
"tbz2",
|
||||
"tga",
|
||||
"tgz",
|
||||
"thmx",
|
||||
"tif",
|
||||
"tiff",
|
||||
"tlz",
|
||||
"ttc",
|
||||
"ttf",
|
||||
"txz",
|
||||
"udf",
|
||||
"uvh",
|
||||
"uvi",
|
||||
"uvm",
|
||||
"uvp",
|
||||
"uvs",
|
||||
"uvu",
|
||||
"viv",
|
||||
"vob",
|
||||
"war",
|
||||
"wav",
|
||||
"wax",
|
||||
"wbmp",
|
||||
"wdp",
|
||||
"weba",
|
||||
"webm",
|
||||
"webp",
|
||||
"whl",
|
||||
"wim",
|
||||
"wm",
|
||||
"wma",
|
||||
"wmv",
|
||||
"wmx",
|
||||
"woff",
|
||||
"woff2",
|
||||
"wrm",
|
||||
"wvx",
|
||||
"xbm",
|
||||
"xif",
|
||||
"xla",
|
||||
"xlam",
|
||||
"xls",
|
||||
"xlsb",
|
||||
"xlsm",
|
||||
"xlsx",
|
||||
"xlt",
|
||||
"xltm",
|
||||
"xltx",
|
||||
"xm",
|
||||
"xmind",
|
||||
"xpi",
|
||||
"xpm",
|
||||
"xwd",
|
||||
"xz",
|
||||
"z",
|
||||
"zip",
|
||||
"zipx"
|
||||
]
|
||||
3
labWeb/lab7/node_modules/binary-extensions/binary-extensions.json.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare const binaryExtensionsJson: readonly string[];
|
||||
|
||||
export = binaryExtensionsJson;
|
||||
14
labWeb/lab7/node_modules/binary-extensions/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
List of binary file extensions.
|
||||
|
||||
@example
|
||||
```
|
||||
import binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
*/
|
||||
declare const binaryExtensions: readonly string[];
|
||||
|
||||
export = binaryExtensions;
|
||||
1
labWeb/lab7/node_modules/binary-extensions/index.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./binary-extensions.json');
|
||||
9
labWeb/lab7/node_modules/binary-extensions/license
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com), Paul Miller (https://paulmillr.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
38
labWeb/lab7/node_modules/binary-extensions/package.json
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "binary-extensions",
|
||||
"version": "2.2.0",
|
||||
"description": "List of binary file extensions",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/binary-extensions",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"binary-extensions.json",
|
||||
"binary-extensions.json.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"binary",
|
||||
"extensions",
|
||||
"extension",
|
||||
"file",
|
||||
"json",
|
||||
"list",
|
||||
"array"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"tsd": "^0.7.2",
|
||||
"xo": "^0.24.0"
|
||||
}
|
||||
}
|
||||
41
labWeb/lab7/node_modules/binary-extensions/readme.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# binary-extensions
|
||||
|
||||
> List of binary file extensions
|
||||
|
||||
The list is just a [JSON file](binary-extensions.json) and can be used anywhere.
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
$ npm install binary-extensions
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const binaryExtensions = require('binary-extensions');
|
||||
|
||||
console.log(binaryExtensions);
|
||||
//=> ['3ds', '3g2', …]
|
||||
```
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file
|
||||
- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions
|
||||
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<b>
|
||||
<a href="https://tidelift.com/subscription/pkg/npm-binary-extensions?utm_source=npm-binary-extensions&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
|
||||
</b>
|
||||
<br>
|
||||
<sub>
|
||||
Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
|
||||
</sub>
|
||||
</div>
|
||||
680
labWeb/lab7/node_modules/body-parser/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
1.20.4 / 2025-12-01
|
||||
===================
|
||||
|
||||
* deps: qs@~6.14.0
|
||||
* deps: use tilde notation for dependencies
|
||||
* deps: http-errors@~2.0.1
|
||||
* deps: raw-body@~2.5.3
|
||||
|
||||
1.20.3 / 2024-09-10
|
||||
===================
|
||||
|
||||
* deps: qs@6.13.0
|
||||
* add `depth` option to customize the depth level in the parser
|
||||
* IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`)
|
||||
|
||||
1.20.2 / 2023-02-21
|
||||
===================
|
||||
|
||||
* Fix strict json error message on Node.js 19+
|
||||
* deps: content-type@~1.0.5
|
||||
- perf: skip value escaping when unnecessary
|
||||
* deps: raw-body@2.5.2
|
||||
|
||||
1.20.1 / 2022-10-06
|
||||
===================
|
||||
|
||||
* deps: qs@6.11.0
|
||||
* perf: remove unnecessary object clone
|
||||
|
||||
1.20.0 / 2022-04-02
|
||||
===================
|
||||
|
||||
* Fix error message for json parse whitespace in `strict`
|
||||
* Fix internal error when inflated body exceeds limit
|
||||
* Prevent loss of async hooks context
|
||||
* Prevent hanging when request already read
|
||||
* deps: depd@2.0.0
|
||||
- Replace internal `eval` usage with `Function` constructor
|
||||
- Use instance methods on `process` to check for listeners
|
||||
* deps: http-errors@2.0.0
|
||||
- deps: depd@2.0.0
|
||||
- deps: statuses@2.0.1
|
||||
* deps: on-finished@2.4.1
|
||||
* deps: qs@6.10.3
|
||||
* deps: raw-body@2.5.1
|
||||
- deps: http-errors@2.0.0
|
||||
|
||||
1.19.2 / 2022-02-15
|
||||
===================
|
||||
|
||||
* deps: bytes@3.1.2
|
||||
* deps: qs@6.9.7
|
||||
* Fix handling of `__proto__` keys
|
||||
* deps: raw-body@2.4.3
|
||||
- deps: bytes@3.1.2
|
||||
|
||||
1.19.1 / 2021-12-10
|
||||
===================
|
||||
|
||||
* deps: bytes@3.1.1
|
||||
* deps: http-errors@1.8.1
|
||||
- deps: inherits@2.0.4
|
||||
- deps: toidentifier@1.0.1
|
||||
- deps: setprototypeof@1.2.0
|
||||
* deps: qs@6.9.6
|
||||
* deps: raw-body@2.4.2
|
||||
- deps: bytes@3.1.1
|
||||
- deps: http-errors@1.8.1
|
||||
* deps: safe-buffer@5.2.1
|
||||
* deps: type-is@~1.6.18
|
||||
|
||||
1.19.0 / 2019-04-25
|
||||
===================
|
||||
|
||||
* deps: bytes@3.1.0
|
||||
- Add petabyte (`pb`) support
|
||||
* deps: http-errors@1.7.2
|
||||
- Set constructor name when possible
|
||||
- deps: setprototypeof@1.1.1
|
||||
- deps: statuses@'>= 1.5.0 < 2'
|
||||
* deps: iconv-lite@0.4.24
|
||||
- Added encoding MIK
|
||||
* deps: qs@6.7.0
|
||||
- Fix parsing array brackets after index
|
||||
* deps: raw-body@2.4.0
|
||||
- deps: bytes@3.1.0
|
||||
- deps: http-errors@1.7.2
|
||||
- deps: iconv-lite@0.4.24
|
||||
* deps: type-is@~1.6.17
|
||||
- deps: mime-types@~2.1.24
|
||||
- perf: prevent internal `throw` on invalid type
|
||||
|
||||
1.18.3 / 2018-05-14
|
||||
===================
|
||||
|
||||
* Fix stack trace for strict json parse error
|
||||
* deps: depd@~1.1.2
|
||||
- perf: remove argument reassignment
|
||||
* deps: http-errors@~1.6.3
|
||||
- deps: depd@~1.1.2
|
||||
- deps: setprototypeof@1.1.0
|
||||
- deps: statuses@'>= 1.3.1 < 2'
|
||||
* deps: iconv-lite@0.4.23
|
||||
- Fix loading encoding with year appended
|
||||
- Fix deprecation warnings on Node.js 10+
|
||||
* deps: qs@6.5.2
|
||||
* deps: raw-body@2.3.3
|
||||
- deps: http-errors@1.6.3
|
||||
- deps: iconv-lite@0.4.23
|
||||
* deps: type-is@~1.6.16
|
||||
- deps: mime-types@~2.1.18
|
||||
|
||||
1.18.2 / 2017-09-22
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.9
|
||||
* perf: remove argument reassignment
|
||||
|
||||
1.18.1 / 2017-09-12
|
||||
===================
|
||||
|
||||
* deps: content-type@~1.0.4
|
||||
- perf: remove argument reassignment
|
||||
- perf: skip parameter parsing when no parameters
|
||||
* deps: iconv-lite@0.4.19
|
||||
- Fix ISO-8859-1 regression
|
||||
- Update Windows-1255
|
||||
* deps: qs@6.5.1
|
||||
- Fix parsing & compacting very deep objects
|
||||
* deps: raw-body@2.3.2
|
||||
- deps: iconv-lite@0.4.19
|
||||
|
||||
1.18.0 / 2017-09-08
|
||||
===================
|
||||
|
||||
* Fix JSON strict violation error to match native parse error
|
||||
* Include the `body` property on verify errors
|
||||
* Include the `type` property on all generated errors
|
||||
* Use `http-errors` to set status code on errors
|
||||
* deps: bytes@3.0.0
|
||||
* deps: debug@2.6.8
|
||||
* deps: depd@~1.1.1
|
||||
- Remove unnecessary `Buffer` loading
|
||||
* deps: http-errors@~1.6.2
|
||||
- deps: depd@1.1.1
|
||||
* deps: iconv-lite@0.4.18
|
||||
- Add support for React Native
|
||||
- Add a warning if not loaded as utf-8
|
||||
- Fix CESU-8 decoding in Node.js 8
|
||||
- Improve speed of ISO-8859-1 encoding
|
||||
* deps: qs@6.5.0
|
||||
* deps: raw-body@2.3.1
|
||||
- Use `http-errors` for standard emitted errors
|
||||
- deps: bytes@3.0.0
|
||||
- deps: iconv-lite@0.4.18
|
||||
- perf: skip buffer decoding on overage chunk
|
||||
* perf: prevent internal `throw` when missing charset
|
||||
|
||||
1.17.2 / 2017-05-17
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.7
|
||||
- Fix `DEBUG_MAX_ARRAY_LENGTH`
|
||||
- deps: ms@2.0.0
|
||||
* deps: type-is@~1.6.15
|
||||
- deps: mime-types@~2.1.15
|
||||
|
||||
1.17.1 / 2017-03-06
|
||||
===================
|
||||
|
||||
* deps: qs@6.4.0
|
||||
- Fix regression parsing keys starting with `[`
|
||||
|
||||
1.17.0 / 2017-03-01
|
||||
===================
|
||||
|
||||
* deps: http-errors@~1.6.1
|
||||
- Make `message` property enumerable for `HttpError`s
|
||||
- deps: setprototypeof@1.0.3
|
||||
* deps: qs@6.3.1
|
||||
- Fix compacting nested arrays
|
||||
|
||||
1.16.1 / 2017-02-10
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.1
|
||||
- Fix deprecation messages in WebStorm and other editors
|
||||
- Undeprecate `DEBUG_FD` set to `1` or `2`
|
||||
|
||||
1.16.0 / 2017-01-17
|
||||
===================
|
||||
|
||||
* deps: debug@2.6.0
|
||||
- Allow colors in workers
|
||||
- Deprecated `DEBUG_FD` environment variable
|
||||
- Fix error when running under React Native
|
||||
- Use same color for same namespace
|
||||
- deps: ms@0.7.2
|
||||
* deps: http-errors@~1.5.1
|
||||
- deps: inherits@2.0.3
|
||||
- deps: setprototypeof@1.0.2
|
||||
- deps: statuses@'>= 1.3.1 < 2'
|
||||
* deps: iconv-lite@0.4.15
|
||||
- Added encoding MS-31J
|
||||
- Added encoding MS-932
|
||||
- Added encoding MS-936
|
||||
- Added encoding MS-949
|
||||
- Added encoding MS-950
|
||||
- Fix GBK/GB18030 handling of Euro character
|
||||
* deps: qs@6.2.1
|
||||
- Fix array parsing from skipping empty values
|
||||
* deps: raw-body@~2.2.0
|
||||
- deps: iconv-lite@0.4.15
|
||||
* deps: type-is@~1.6.14
|
||||
- deps: mime-types@~2.1.13
|
||||
|
||||
1.15.2 / 2016-06-19
|
||||
===================
|
||||
|
||||
* deps: bytes@2.4.0
|
||||
* deps: content-type@~1.0.2
|
||||
- perf: enable strict mode
|
||||
* deps: http-errors@~1.5.0
|
||||
- Use `setprototypeof` module to replace `__proto__` setting
|
||||
- deps: statuses@'>= 1.3.0 < 2'
|
||||
- perf: enable strict mode
|
||||
* deps: qs@6.2.0
|
||||
* deps: raw-body@~2.1.7
|
||||
- deps: bytes@2.4.0
|
||||
- perf: remove double-cleanup on happy path
|
||||
* deps: type-is@~1.6.13
|
||||
- deps: mime-types@~2.1.11
|
||||
|
||||
1.15.1 / 2016-05-05
|
||||
===================
|
||||
|
||||
* deps: bytes@2.3.0
|
||||
- Drop partial bytes on all parsed units
|
||||
- Fix parsing byte string that looks like hex
|
||||
* deps: raw-body@~2.1.6
|
||||
- deps: bytes@2.3.0
|
||||
* deps: type-is@~1.6.12
|
||||
- deps: mime-types@~2.1.10
|
||||
|
||||
1.15.0 / 2016-02-10
|
||||
===================
|
||||
|
||||
* deps: http-errors@~1.4.0
|
||||
- Add `HttpError` export, for `err instanceof createError.HttpError`
|
||||
- deps: inherits@2.0.1
|
||||
- deps: statuses@'>= 1.2.1 < 2'
|
||||
* deps: qs@6.1.0
|
||||
* deps: type-is@~1.6.11
|
||||
- deps: mime-types@~2.1.9
|
||||
|
||||
1.14.2 / 2015-12-16
|
||||
===================
|
||||
|
||||
* deps: bytes@2.2.0
|
||||
* deps: iconv-lite@0.4.13
|
||||
* deps: qs@5.2.0
|
||||
* deps: raw-body@~2.1.5
|
||||
- deps: bytes@2.2.0
|
||||
- deps: iconv-lite@0.4.13
|
||||
* deps: type-is@~1.6.10
|
||||
- deps: mime-types@~2.1.8
|
||||
|
||||
1.14.1 / 2015-09-27
|
||||
===================
|
||||
|
||||
* Fix issue where invalid charset results in 400 when `verify` used
|
||||
* deps: iconv-lite@0.4.12
|
||||
- Fix CESU-8 decoding in Node.js 4.x
|
||||
* deps: raw-body@~2.1.4
|
||||
- Fix masking critical errors from `iconv-lite`
|
||||
- deps: iconv-lite@0.4.12
|
||||
* deps: type-is@~1.6.9
|
||||
- deps: mime-types@~2.1.7
|
||||
|
||||
1.14.0 / 2015-09-16
|
||||
===================
|
||||
|
||||
* Fix JSON strict parse error to match syntax errors
|
||||
* Provide static `require` analysis in `urlencoded` parser
|
||||
* deps: depd@~1.1.0
|
||||
- Support web browser loading
|
||||
* deps: qs@5.1.0
|
||||
* deps: raw-body@~2.1.3
|
||||
- Fix sync callback when attaching data listener causes sync read
|
||||
* deps: type-is@~1.6.8
|
||||
- Fix type error when given invalid type to match against
|
||||
- deps: mime-types@~2.1.6
|
||||
|
||||
1.13.3 / 2015-07-31
|
||||
===================
|
||||
|
||||
* deps: type-is@~1.6.6
|
||||
- deps: mime-types@~2.1.4
|
||||
|
||||
1.13.2 / 2015-07-05
|
||||
===================
|
||||
|
||||
* deps: iconv-lite@0.4.11
|
||||
* deps: qs@4.0.0
|
||||
- Fix dropping parameters like `hasOwnProperty`
|
||||
- Fix user-visible incompatibilities from 3.1.0
|
||||
- Fix various parsing edge cases
|
||||
* deps: raw-body@~2.1.2
|
||||
- Fix error stack traces to skip `makeError`
|
||||
- deps: iconv-lite@0.4.11
|
||||
* deps: type-is@~1.6.4
|
||||
- deps: mime-types@~2.1.2
|
||||
- perf: enable strict mode
|
||||
- perf: remove argument reassignment
|
||||
|
||||
1.13.1 / 2015-06-16
|
||||
===================
|
||||
|
||||
* deps: qs@2.4.2
|
||||
- Downgraded from 3.1.0 because of user-visible incompatibilities
|
||||
|
||||
1.13.0 / 2015-06-14
|
||||
===================
|
||||
|
||||
* Add `statusCode` property on `Error`s, in addition to `status`
|
||||
* Change `type` default to `application/json` for JSON parser
|
||||
* Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
|
||||
* Provide static `require` analysis
|
||||
* Use the `http-errors` module to generate errors
|
||||
* deps: bytes@2.1.0
|
||||
- Slight optimizations
|
||||
* deps: iconv-lite@0.4.10
|
||||
- The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails
|
||||
- Leading BOM is now removed when decoding
|
||||
* deps: on-finished@~2.3.0
|
||||
- Add defined behavior for HTTP `CONNECT` requests
|
||||
- Add defined behavior for HTTP `Upgrade` requests
|
||||
- deps: ee-first@1.1.1
|
||||
* deps: qs@3.1.0
|
||||
- Fix dropping parameters like `hasOwnProperty`
|
||||
- Fix various parsing edge cases
|
||||
- Parsed object now has `null` prototype
|
||||
* deps: raw-body@~2.1.1
|
||||
- Use `unpipe` module for unpiping requests
|
||||
- deps: iconv-lite@0.4.10
|
||||
* deps: type-is@~1.6.3
|
||||
- deps: mime-types@~2.1.1
|
||||
- perf: reduce try block size
|
||||
- perf: remove bitwise operations
|
||||
* perf: enable strict mode
|
||||
* perf: remove argument reassignment
|
||||
* perf: remove delete call
|
||||
|
||||
1.12.4 / 2015-05-10
|
||||
===================
|
||||
|
||||
* deps: debug@~2.2.0
|
||||
* deps: qs@2.4.2
|
||||
- Fix allowing parameters like `constructor`
|
||||
* deps: on-finished@~2.2.1
|
||||
* deps: raw-body@~2.0.1
|
||||
- Fix a false-positive when unpiping in Node.js 0.8
|
||||
- deps: bytes@2.0.1
|
||||
* deps: type-is@~1.6.2
|
||||
- deps: mime-types@~2.0.11
|
||||
|
||||
1.12.3 / 2015-04-15
|
||||
===================
|
||||
|
||||
* Slight efficiency improvement when not debugging
|
||||
* deps: depd@~1.0.1
|
||||
* deps: iconv-lite@0.4.8
|
||||
- Add encoding alias UNICODE-1-1-UTF-7
|
||||
* deps: raw-body@1.3.4
|
||||
- Fix hanging callback if request aborts during read
|
||||
- deps: iconv-lite@0.4.8
|
||||
|
||||
1.12.2 / 2015-03-16
|
||||
===================
|
||||
|
||||
* deps: qs@2.4.1
|
||||
- Fix error when parameter `hasOwnProperty` is present
|
||||
|
||||
1.12.1 / 2015-03-15
|
||||
===================
|
||||
|
||||
* deps: debug@~2.1.3
|
||||
- Fix high intensity foreground color for bold
|
||||
- deps: ms@0.7.0
|
||||
* deps: type-is@~1.6.1
|
||||
- deps: mime-types@~2.0.10
|
||||
|
||||
1.12.0 / 2015-02-13
|
||||
===================
|
||||
|
||||
* add `debug` messages
|
||||
* accept a function for the `type` option
|
||||
* use `content-type` to parse `Content-Type` headers
|
||||
* deps: iconv-lite@0.4.7
|
||||
- Gracefully support enumerables on `Object.prototype`
|
||||
* deps: raw-body@1.3.3
|
||||
- deps: iconv-lite@0.4.7
|
||||
* deps: type-is@~1.6.0
|
||||
- fix argument reassignment
|
||||
- fix false-positives in `hasBody` `Transfer-Encoding` check
|
||||
- support wildcard for both type and subtype (`*/*`)
|
||||
- deps: mime-types@~2.0.9
|
||||
|
||||
1.11.0 / 2015-01-30
|
||||
===================
|
||||
|
||||
* make internal `extended: true` depth limit infinity
|
||||
* deps: type-is@~1.5.6
|
||||
- deps: mime-types@~2.0.8
|
||||
|
||||
1.10.2 / 2015-01-20
|
||||
===================
|
||||
|
||||
* deps: iconv-lite@0.4.6
|
||||
- Fix rare aliases of single-byte encodings
|
||||
* deps: raw-body@1.3.2
|
||||
- deps: iconv-lite@0.4.6
|
||||
|
||||
1.10.1 / 2015-01-01
|
||||
===================
|
||||
|
||||
* deps: on-finished@~2.2.0
|
||||
* deps: type-is@~1.5.5
|
||||
- deps: mime-types@~2.0.7
|
||||
|
||||
1.10.0 / 2014-12-02
|
||||
===================
|
||||
|
||||
* make internal `extended: true` array limit dynamic
|
||||
|
||||
1.9.3 / 2014-11-21
|
||||
==================
|
||||
|
||||
* deps: iconv-lite@0.4.5
|
||||
- Fix Windows-31J and X-SJIS encoding support
|
||||
* deps: qs@2.3.3
|
||||
- Fix `arrayLimit` behavior
|
||||
* deps: raw-body@1.3.1
|
||||
- deps: iconv-lite@0.4.5
|
||||
* deps: type-is@~1.5.3
|
||||
- deps: mime-types@~2.0.3
|
||||
|
||||
1.9.2 / 2014-10-27
|
||||
==================
|
||||
|
||||
* deps: qs@2.3.2
|
||||
- Fix parsing of mixed objects and values
|
||||
|
||||
1.9.1 / 2014-10-22
|
||||
==================
|
||||
|
||||
* deps: on-finished@~2.1.1
|
||||
- Fix handling of pipelined requests
|
||||
* deps: qs@2.3.0
|
||||
- Fix parsing of mixed implicit and explicit arrays
|
||||
* deps: type-is@~1.5.2
|
||||
- deps: mime-types@~2.0.2
|
||||
|
||||
1.9.0 / 2014-09-24
|
||||
==================
|
||||
|
||||
* include the charset in "unsupported charset" error message
|
||||
* include the encoding in "unsupported content encoding" error message
|
||||
* deps: depd@~1.0.0
|
||||
|
||||
1.8.4 / 2014-09-23
|
||||
==================
|
||||
|
||||
* fix content encoding to be case-insensitive
|
||||
|
||||
1.8.3 / 2014-09-19
|
||||
==================
|
||||
|
||||
* deps: qs@2.2.4
|
||||
- Fix issue with object keys starting with numbers truncated
|
||||
|
||||
1.8.2 / 2014-09-15
|
||||
==================
|
||||
|
||||
* deps: depd@0.4.5
|
||||
|
||||
1.8.1 / 2014-09-07
|
||||
==================
|
||||
|
||||
* deps: media-typer@0.3.0
|
||||
* deps: type-is@~1.5.1
|
||||
|
||||
1.8.0 / 2014-09-05
|
||||
==================
|
||||
|
||||
* make empty-body-handling consistent between chunked requests
|
||||
- empty `json` produces `{}`
|
||||
- empty `raw` produces `new Buffer(0)`
|
||||
- empty `text` produces `''`
|
||||
- empty `urlencoded` produces `{}`
|
||||
* deps: qs@2.2.3
|
||||
- Fix issue where first empty value in array is discarded
|
||||
* deps: type-is@~1.5.0
|
||||
- fix `hasbody` to be true for `content-length: 0`
|
||||
|
||||
1.7.0 / 2014-09-01
|
||||
==================
|
||||
|
||||
* add `parameterLimit` option to `urlencoded` parser
|
||||
* change `urlencoded` extended array limit to 100
|
||||
* respond with 413 when over `parameterLimit` in `urlencoded`
|
||||
|
||||
1.6.7 / 2014-08-29
|
||||
==================
|
||||
|
||||
* deps: qs@2.2.2
|
||||
- Remove unnecessary cloning
|
||||
|
||||
1.6.6 / 2014-08-27
|
||||
==================
|
||||
|
||||
* deps: qs@2.2.0
|
||||
- Array parsing fix
|
||||
- Performance improvements
|
||||
|
||||
1.6.5 / 2014-08-16
|
||||
==================
|
||||
|
||||
* deps: on-finished@2.1.0
|
||||
|
||||
1.6.4 / 2014-08-14
|
||||
==================
|
||||
|
||||
* deps: qs@1.2.2
|
||||
|
||||
1.6.3 / 2014-08-10
|
||||
==================
|
||||
|
||||
* deps: qs@1.2.1
|
||||
|
||||
1.6.2 / 2014-08-07
|
||||
==================
|
||||
|
||||
* deps: qs@1.2.0
|
||||
- Fix parsing array of objects
|
||||
|
||||
1.6.1 / 2014-08-06
|
||||
==================
|
||||
|
||||
* deps: qs@1.1.0
|
||||
- Accept urlencoded square brackets
|
||||
- Accept empty values in implicit array notation
|
||||
|
||||
1.6.0 / 2014-08-05
|
||||
==================
|
||||
|
||||
* deps: qs@1.0.2
|
||||
- Complete rewrite
|
||||
- Limits array length to 20
|
||||
- Limits object depth to 5
|
||||
- Limits parameters to 1,000
|
||||
|
||||
1.5.2 / 2014-07-27
|
||||
==================
|
||||
|
||||
* deps: depd@0.4.4
|
||||
- Work-around v8 generating empty stack traces
|
||||
|
||||
1.5.1 / 2014-07-26
|
||||
==================
|
||||
|
||||
* deps: depd@0.4.3
|
||||
- Fix exception when global `Error.stackTraceLimit` is too low
|
||||
|
||||
1.5.0 / 2014-07-20
|
||||
==================
|
||||
|
||||
* deps: depd@0.4.2
|
||||
- Add `TRACE_DEPRECATION` environment variable
|
||||
- Remove non-standard grey color from color output
|
||||
- Support `--no-deprecation` argument
|
||||
- Support `--trace-deprecation` argument
|
||||
* deps: iconv-lite@0.4.4
|
||||
- Added encoding UTF-7
|
||||
* deps: raw-body@1.3.0
|
||||
- deps: iconv-lite@0.4.4
|
||||
- Added encoding UTF-7
|
||||
- Fix `Cannot switch to old mode now` error on Node.js 0.10+
|
||||
* deps: type-is@~1.3.2
|
||||
|
||||
1.4.3 / 2014-06-19
|
||||
==================
|
||||
|
||||
* deps: type-is@1.3.1
|
||||
- fix global variable leak
|
||||
|
||||
1.4.2 / 2014-06-19
|
||||
==================
|
||||
|
||||
* deps: type-is@1.3.0
|
||||
- improve type parsing
|
||||
|
||||
1.4.1 / 2014-06-19
|
||||
==================
|
||||
|
||||
* fix urlencoded extended deprecation message
|
||||
|
||||
1.4.0 / 2014-06-19
|
||||
==================
|
||||
|
||||
* add `text` parser
|
||||
* add `raw` parser
|
||||
* check accepted charset in content-type (accepts utf-8)
|
||||
* check accepted encoding in content-encoding (accepts identity)
|
||||
* deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed
|
||||
* deprecate `urlencoded()` without provided `extended` option
|
||||
* lazy-load urlencoded parsers
|
||||
* parsers split into files for reduced mem usage
|
||||
* support gzip and deflate bodies
|
||||
- set `inflate: false` to turn off
|
||||
* deps: raw-body@1.2.2
|
||||
- Support all encodings from `iconv-lite`
|
||||
|
||||
1.3.1 / 2014-06-11
|
||||
==================
|
||||
|
||||
* deps: type-is@1.2.1
|
||||
- Switch dependency from mime to mime-types@1.0.0
|
||||
|
||||
1.3.0 / 2014-05-31
|
||||
==================
|
||||
|
||||
* add `extended` option to urlencoded parser
|
||||
|
||||
1.2.2 / 2014-05-27
|
||||
==================
|
||||
|
||||
* deps: raw-body@1.1.6
|
||||
- assert stream encoding on node.js 0.8
|
||||
- assert stream encoding on node.js < 0.10.6
|
||||
- deps: bytes@1
|
||||
|
||||
1.2.1 / 2014-05-26
|
||||
==================
|
||||
|
||||
* invoke `next(err)` after request fully read
|
||||
- prevents hung responses and socket hang ups
|
||||
|
||||
1.2.0 / 2014-05-11
|
||||
==================
|
||||
|
||||
* add `verify` option
|
||||
* deps: type-is@1.2.0
|
||||
- support suffix matching
|
||||
|
||||
1.1.2 / 2014-05-11
|
||||
==================
|
||||
|
||||
* improve json parser speed
|
||||
|
||||
1.1.1 / 2014-05-11
|
||||
==================
|
||||
|
||||
* fix repeated limit parsing with every request
|
||||
|
||||
1.1.0 / 2014-05-10
|
||||
==================
|
||||
|
||||
* add `type` option
|
||||
* deps: pin for safety and consistency
|
||||
|
||||
1.0.2 / 2014-04-14
|
||||
==================
|
||||
|
||||
* use `type-is` module
|
||||
|
||||
1.0.1 / 2014-03-20
|
||||
==================
|
||||
|
||||
* lower default limits to 100kb
|
||||
23
labWeb/lab7/node_modules/body-parser/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
|
||||
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
476
labWeb/lab7/node_modules/body-parser/README.md
generated
vendored
Normal file
@@ -0,0 +1,476 @@
|
||||
# body-parser
|
||||
|
||||
[![NPM Version][npm-version-image]][npm-url]
|
||||
[![NPM Downloads][npm-downloads-image]][npm-url]
|
||||
[![Build Status][ci-image]][ci-url]
|
||||
[![Test Coverage][coveralls-image]][coveralls-url]
|
||||
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
|
||||
|
||||
Node.js body parsing middleware.
|
||||
|
||||
Parse incoming request bodies in a middleware before your handlers, available
|
||||
under the `req.body` property.
|
||||
|
||||
**Note** As `req.body`'s shape is based on user-controlled input, all
|
||||
properties and values in this object are untrusted and should be validated
|
||||
before trusting. For example, `req.body.foo.toString()` may fail in multiple
|
||||
ways, for example the `foo` property may not be there or may not be a string,
|
||||
and `toString` may not be a function and instead a string or other user input.
|
||||
|
||||
[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/).
|
||||
|
||||
_This does not handle multipart bodies_, due to their complex and typically
|
||||
large nature. For multipart bodies, you may be interested in the following
|
||||
modules:
|
||||
|
||||
* [busboy](https://www.npmjs.org/package/busboy#readme) and
|
||||
[connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)
|
||||
* [multiparty](https://www.npmjs.org/package/multiparty#readme) and
|
||||
[connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)
|
||||
* [formidable](https://www.npmjs.org/package/formidable#readme)
|
||||
* [multer](https://www.npmjs.org/package/multer#readme)
|
||||
|
||||
This module provides the following parsers:
|
||||
|
||||
* [JSON body parser](#bodyparserjsonoptions)
|
||||
* [Raw body parser](#bodyparserrawoptions)
|
||||
* [Text body parser](#bodyparsertextoptions)
|
||||
* [URL-encoded form body parser](#bodyparserurlencodedoptions)
|
||||
|
||||
Other body parsers you might be interested in:
|
||||
|
||||
- [body](https://www.npmjs.org/package/body#readme)
|
||||
- [co-body](https://www.npmjs.org/package/co-body#readme)
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ npm install body-parser
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var bodyParser = require('body-parser')
|
||||
```
|
||||
|
||||
The `bodyParser` object exposes various factories to create middlewares. All
|
||||
middlewares will populate the `req.body` property with the parsed body when
|
||||
the `Content-Type` request header matches the `type` option, or an empty
|
||||
object (`{}`) if there was no body to parse, the `Content-Type` was not matched,
|
||||
or an error occurred.
|
||||
|
||||
The various errors returned by this module are described in the
|
||||
[errors section](#errors).
|
||||
|
||||
### bodyParser.json([options])
|
||||
|
||||
Returns middleware that only parses `json` and only looks at requests where
|
||||
the `Content-Type` header matches the `type` option. This parser accepts any
|
||||
Unicode encoding of the body and supports automatic inflation of `gzip` and
|
||||
`deflate` encodings.
|
||||
|
||||
A new `body` object containing the parsed data is populated on the `request`
|
||||
object after the middleware (i.e. `req.body`).
|
||||
|
||||
#### Options
|
||||
|
||||
The `json` function takes an optional `options` object that may contain any of
|
||||
the following keys:
|
||||
|
||||
##### inflate
|
||||
|
||||
When set to `true`, then deflated (compressed) bodies will be inflated; when
|
||||
`false`, deflated bodies are rejected. Defaults to `true`.
|
||||
|
||||
##### limit
|
||||
|
||||
Controls the maximum request body size. If this is a number, then the value
|
||||
specifies the number of bytes; if it is a string, the value is passed to the
|
||||
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
|
||||
to `'100kb'`.
|
||||
|
||||
##### reviver
|
||||
|
||||
The `reviver` option is passed directly to `JSON.parse` as the second
|
||||
argument. You can find more information on this argument
|
||||
[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
|
||||
|
||||
##### strict
|
||||
|
||||
When set to `true`, will only accept arrays and objects; when `false` will
|
||||
accept anything `JSON.parse` accepts. Defaults to `true`.
|
||||
|
||||
##### type
|
||||
|
||||
The `type` option is used to determine what media type the middleware will
|
||||
parse. This option can be a string, array of strings, or a function. If not a
|
||||
function, `type` option is passed directly to the
|
||||
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
|
||||
be an extension name (like `json`), a mime type (like `application/json`), or
|
||||
a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
|
||||
option is called as `fn(req)` and the request is parsed if it returns a truthy
|
||||
value. Defaults to `application/json`.
|
||||
|
||||
##### verify
|
||||
|
||||
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
|
||||
where `buf` is a `Buffer` of the raw request body and `encoding` is the
|
||||
encoding of the request. The parsing can be aborted by throwing an error.
|
||||
|
||||
### bodyParser.raw([options])
|
||||
|
||||
Returns middleware that parses all bodies as a `Buffer` and only looks at
|
||||
requests where the `Content-Type` header matches the `type` option. This
|
||||
parser supports automatic inflation of `gzip` and `deflate` encodings.
|
||||
|
||||
A new `body` object containing the parsed data is populated on the `request`
|
||||
object after the middleware (i.e. `req.body`). This will be a `Buffer` object
|
||||
of the body.
|
||||
|
||||
#### Options
|
||||
|
||||
The `raw` function takes an optional `options` object that may contain any of
|
||||
the following keys:
|
||||
|
||||
##### inflate
|
||||
|
||||
When set to `true`, then deflated (compressed) bodies will be inflated; when
|
||||
`false`, deflated bodies are rejected. Defaults to `true`.
|
||||
|
||||
##### limit
|
||||
|
||||
Controls the maximum request body size. If this is a number, then the value
|
||||
specifies the number of bytes; if it is a string, the value is passed to the
|
||||
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
|
||||
to `'100kb'`.
|
||||
|
||||
##### type
|
||||
|
||||
The `type` option is used to determine what media type the middleware will
|
||||
parse. This option can be a string, array of strings, or a function.
|
||||
If not a function, `type` option is passed directly to the
|
||||
[type-is](https://www.npmjs.org/package/type-is#readme) library and this
|
||||
can be an extension name (like `bin`), a mime type (like
|
||||
`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
|
||||
`application/*`). If a function, the `type` option is called as `fn(req)`
|
||||
and the request is parsed if it returns a truthy value. Defaults to
|
||||
`application/octet-stream`.
|
||||
|
||||
##### verify
|
||||
|
||||
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
|
||||
where `buf` is a `Buffer` of the raw request body and `encoding` is the
|
||||
encoding of the request. The parsing can be aborted by throwing an error.
|
||||
|
||||
### bodyParser.text([options])
|
||||
|
||||
Returns middleware that parses all bodies as a string and only looks at
|
||||
requests where the `Content-Type` header matches the `type` option. This
|
||||
parser supports automatic inflation of `gzip` and `deflate` encodings.
|
||||
|
||||
A new `body` string containing the parsed data is populated on the `request`
|
||||
object after the middleware (i.e. `req.body`). This will be a string of the
|
||||
body.
|
||||
|
||||
#### Options
|
||||
|
||||
The `text` function takes an optional `options` object that may contain any of
|
||||
the following keys:
|
||||
|
||||
##### defaultCharset
|
||||
|
||||
Specify the default character set for the text content if the charset is not
|
||||
specified in the `Content-Type` header of the request. Defaults to `utf-8`.
|
||||
|
||||
##### inflate
|
||||
|
||||
When set to `true`, then deflated (compressed) bodies will be inflated; when
|
||||
`false`, deflated bodies are rejected. Defaults to `true`.
|
||||
|
||||
##### limit
|
||||
|
||||
Controls the maximum request body size. If this is a number, then the value
|
||||
specifies the number of bytes; if it is a string, the value is passed to the
|
||||
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
|
||||
to `'100kb'`.
|
||||
|
||||
##### type
|
||||
|
||||
The `type` option is used to determine what media type the middleware will
|
||||
parse. This option can be a string, array of strings, or a function. If not
|
||||
a function, `type` option is passed directly to the
|
||||
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
|
||||
be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
|
||||
type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
|
||||
option is called as `fn(req)` and the request is parsed if it returns a
|
||||
truthy value. Defaults to `text/plain`.
|
||||
|
||||
##### verify
|
||||
|
||||
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
|
||||
where `buf` is a `Buffer` of the raw request body and `encoding` is the
|
||||
encoding of the request. The parsing can be aborted by throwing an error.
|
||||
|
||||
### bodyParser.urlencoded([options])
|
||||
|
||||
Returns middleware that only parses `urlencoded` bodies and only looks at
|
||||
requests where the `Content-Type` header matches the `type` option. This
|
||||
parser accepts only UTF-8 encoding of the body and supports automatic
|
||||
inflation of `gzip` and `deflate` encodings.
|
||||
|
||||
A new `body` object containing the parsed data is populated on the `request`
|
||||
object after the middleware (i.e. `req.body`). This object will contain
|
||||
key-value pairs, where the value can be a string or array (when `extended` is
|
||||
`false`), or any type (when `extended` is `true`).
|
||||
|
||||
#### Options
|
||||
|
||||
The `urlencoded` function takes an optional `options` object that may contain
|
||||
any of the following keys:
|
||||
|
||||
##### extended
|
||||
|
||||
The `extended` option allows to choose between parsing the URL-encoded data
|
||||
with the `querystring` library (when `false`) or the `qs` library (when
|
||||
`true`). The "extended" syntax allows for rich objects and arrays to be
|
||||
encoded into the URL-encoded format, allowing for a JSON-like experience
|
||||
with URL-encoded. For more information, please
|
||||
[see the qs library](https://www.npmjs.org/package/qs#readme).
|
||||
|
||||
Defaults to `true`, but using the default has been deprecated. Please
|
||||
research into the difference between `qs` and `querystring` and choose the
|
||||
appropriate setting.
|
||||
|
||||
##### inflate
|
||||
|
||||
When set to `true`, then deflated (compressed) bodies will be inflated; when
|
||||
`false`, deflated bodies are rejected. Defaults to `true`.
|
||||
|
||||
##### limit
|
||||
|
||||
Controls the maximum request body size. If this is a number, then the value
|
||||
specifies the number of bytes; if it is a string, the value is passed to the
|
||||
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
|
||||
to `'100kb'`.
|
||||
|
||||
##### parameterLimit
|
||||
|
||||
The `parameterLimit` option controls the maximum number of parameters that
|
||||
are allowed in the URL-encoded data. If a request contains more parameters
|
||||
than this value, a 413 will be returned to the client. Defaults to `1000`.
|
||||
|
||||
##### type
|
||||
|
||||
The `type` option is used to determine what media type the middleware will
|
||||
parse. This option can be a string, array of strings, or a function. If not
|
||||
a function, `type` option is passed directly to the
|
||||
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
|
||||
be an extension name (like `urlencoded`), a mime type (like
|
||||
`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
|
||||
`*/x-www-form-urlencoded`). If a function, the `type` option is called as
|
||||
`fn(req)` and the request is parsed if it returns a truthy value. Defaults
|
||||
to `application/x-www-form-urlencoded`.
|
||||
|
||||
##### verify
|
||||
|
||||
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
|
||||
where `buf` is a `Buffer` of the raw request body and `encoding` is the
|
||||
encoding of the request. The parsing can be aborted by throwing an error.
|
||||
|
||||
#### depth
|
||||
|
||||
The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
|
||||
|
||||
## Errors
|
||||
|
||||
The middlewares provided by this module create errors using the
|
||||
[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
|
||||
will typically have a `status`/`statusCode` property that contains the suggested
|
||||
HTTP response code, an `expose` property to determine if the `message` property
|
||||
should be displayed to the client, a `type` property to determine the type of
|
||||
error without matching against the `message`, and a `body` property containing
|
||||
the read body, if available.
|
||||
|
||||
The following are the common errors created, though any error can come through
|
||||
for various reasons.
|
||||
|
||||
### content encoding unsupported
|
||||
|
||||
This error will occur when the request had a `Content-Encoding` header that
|
||||
contained an encoding but the "inflation" option was set to `false`. The
|
||||
`status` property is set to `415`, the `type` property is set to
|
||||
`'encoding.unsupported'`, and the `charset` property will be set to the
|
||||
encoding that is unsupported.
|
||||
|
||||
### entity parse failed
|
||||
|
||||
This error will occur when the request contained an entity that could not be
|
||||
parsed by the middleware. The `status` property is set to `400`, the `type`
|
||||
property is set to `'entity.parse.failed'`, and the `body` property is set to
|
||||
the entity value that failed parsing.
|
||||
|
||||
### entity verify failed
|
||||
|
||||
This error will occur when the request contained an entity that could not be
|
||||
failed verification by the defined `verify` option. The `status` property is
|
||||
set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
|
||||
`body` property is set to the entity value that failed verification.
|
||||
|
||||
### request aborted
|
||||
|
||||
This error will occur when the request is aborted by the client before reading
|
||||
the body has finished. The `received` property will be set to the number of
|
||||
bytes received before the request was aborted and the `expected` property is
|
||||
set to the number of expected bytes. The `status` property is set to `400`
|
||||
and `type` property is set to `'request.aborted'`.
|
||||
|
||||
### request entity too large
|
||||
|
||||
This error will occur when the request body's size is larger than the "limit"
|
||||
option. The `limit` property will be set to the byte limit and the `length`
|
||||
property will be set to the request body's length. The `status` property is
|
||||
set to `413` and the `type` property is set to `'entity.too.large'`.
|
||||
|
||||
### request size did not match content length
|
||||
|
||||
This error will occur when the request's length did not match the length from
|
||||
the `Content-Length` header. This typically occurs when the request is malformed,
|
||||
typically when the `Content-Length` header was calculated based on characters
|
||||
instead of bytes. The `status` property is set to `400` and the `type` property
|
||||
is set to `'request.size.invalid'`.
|
||||
|
||||
### stream encoding should not be set
|
||||
|
||||
This error will occur when something called the `req.setEncoding` method prior
|
||||
to this middleware. This module operates directly on bytes only and you cannot
|
||||
call `req.setEncoding` when using this module. The `status` property is set to
|
||||
`500` and the `type` property is set to `'stream.encoding.set'`.
|
||||
|
||||
### stream is not readable
|
||||
|
||||
This error will occur when the request is no longer readable when this middleware
|
||||
attempts to read it. This typically means something other than a middleware from
|
||||
this module read the request body already and the middleware was also configured to
|
||||
read the same request. The `status` property is set to `500` and the `type`
|
||||
property is set to `'stream.not.readable'`.
|
||||
|
||||
### too many parameters
|
||||
|
||||
This error will occur when the content of the request exceeds the configured
|
||||
`parameterLimit` for the `urlencoded` parser. The `status` property is set to
|
||||
`413` and the `type` property is set to `'parameters.too.many'`.
|
||||
|
||||
### unsupported charset "BOGUS"
|
||||
|
||||
This error will occur when the request had a charset parameter in the
|
||||
`Content-Type` header, but the `iconv-lite` module does not support it OR the
|
||||
parser does not support it. The charset is contained in the message as well
|
||||
as in the `charset` property. The `status` property is set to `415`, the
|
||||
`type` property is set to `'charset.unsupported'`, and the `charset` property
|
||||
is set to the charset that is unsupported.
|
||||
|
||||
### unsupported content encoding "bogus"
|
||||
|
||||
This error will occur when the request had a `Content-Encoding` header that
|
||||
contained an unsupported encoding. The encoding is contained in the message
|
||||
as well as in the `encoding` property. The `status` property is set to `415`,
|
||||
the `type` property is set to `'encoding.unsupported'`, and the `encoding`
|
||||
property is set to the encoding that is unsupported.
|
||||
|
||||
### The input exceeded the depth
|
||||
|
||||
This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
|
||||
|
||||
## Examples
|
||||
|
||||
### Express/Connect top-level generic
|
||||
|
||||
This example demonstrates adding a generic JSON and URL-encoded parser as a
|
||||
top-level middleware, which will parse the bodies of all incoming requests.
|
||||
This is the simplest setup.
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var bodyParser = require('body-parser')
|
||||
|
||||
var app = express()
|
||||
|
||||
// parse application/x-www-form-urlencoded
|
||||
app.use(bodyParser.urlencoded({ extended: false }))
|
||||
|
||||
// parse application/json
|
||||
app.use(bodyParser.json())
|
||||
|
||||
app.use(function (req, res) {
|
||||
res.setHeader('Content-Type', 'text/plain')
|
||||
res.write('you posted:\n')
|
||||
res.end(JSON.stringify(req.body, null, 2))
|
||||
})
|
||||
```
|
||||
|
||||
### Express route-specific
|
||||
|
||||
This example demonstrates adding body parsers specifically to the routes that
|
||||
need them. In general, this is the most recommended way to use body-parser with
|
||||
Express.
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var bodyParser = require('body-parser')
|
||||
|
||||
var app = express()
|
||||
|
||||
// create application/json parser
|
||||
var jsonParser = bodyParser.json()
|
||||
|
||||
// create application/x-www-form-urlencoded parser
|
||||
var urlencodedParser = bodyParser.urlencoded({ extended: false })
|
||||
|
||||
// POST /login gets urlencoded bodies
|
||||
app.post('/login', urlencodedParser, function (req, res) {
|
||||
res.send('welcome, ' + req.body.username)
|
||||
})
|
||||
|
||||
// POST /api/users gets JSON bodies
|
||||
app.post('/api/users', jsonParser, function (req, res) {
|
||||
// create user in req.body
|
||||
})
|
||||
```
|
||||
|
||||
### Change accepted type for parsers
|
||||
|
||||
All the parsers accept a `type` option which allows you to change the
|
||||
`Content-Type` that the middleware will parse.
|
||||
|
||||
```js
|
||||
var express = require('express')
|
||||
var bodyParser = require('body-parser')
|
||||
|
||||
var app = express()
|
||||
|
||||
// parse various different custom JSON types as JSON
|
||||
app.use(bodyParser.json({ type: 'application/*+json' }))
|
||||
|
||||
// parse some custom thing into a Buffer
|
||||
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
|
||||
|
||||
// parse an HTML body into a string
|
||||
app.use(bodyParser.text({ type: 'text/html' }))
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
[ci-image]: https://badgen.net/github/checks/expressjs/body-parser/master?label=ci
|
||||
[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
|
||||
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/body-parser/master
|
||||
[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
|
||||
[node-version-image]: https://badgen.net/npm/node/body-parser
|
||||
[node-version-url]: https://nodejs.org/en/download
|
||||
[npm-downloads-image]: https://badgen.net/npm/dm/body-parser
|
||||
[npm-url]: https://npmjs.org/package/body-parser
|
||||
[npm-version-image]: https://badgen.net/npm/v/body-parser
|
||||
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
|
||||
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser
|
||||
156
labWeb/lab7/node_modules/body-parser/index.js
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*!
|
||||
* body-parser
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var deprecate = require('depd')('body-parser')
|
||||
|
||||
/**
|
||||
* Cache of loaded parsers.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var parsers = Object.create(null)
|
||||
|
||||
/**
|
||||
* @typedef Parsers
|
||||
* @type {function}
|
||||
* @property {function} json
|
||||
* @property {function} raw
|
||||
* @property {function} text
|
||||
* @property {function} urlencoded
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
* @type {Parsers}
|
||||
*/
|
||||
|
||||
exports = module.exports = deprecate.function(bodyParser,
|
||||
'bodyParser: use individual json/urlencoded middlewares')
|
||||
|
||||
/**
|
||||
* JSON parser.
|
||||
* @public
|
||||
*/
|
||||
|
||||
Object.defineProperty(exports, 'json', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: createParserGetter('json')
|
||||
})
|
||||
|
||||
/**
|
||||
* Raw parser.
|
||||
* @public
|
||||
*/
|
||||
|
||||
Object.defineProperty(exports, 'raw', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: createParserGetter('raw')
|
||||
})
|
||||
|
||||
/**
|
||||
* Text parser.
|
||||
* @public
|
||||
*/
|
||||
|
||||
Object.defineProperty(exports, 'text', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: createParserGetter('text')
|
||||
})
|
||||
|
||||
/**
|
||||
* URL-encoded parser.
|
||||
* @public
|
||||
*/
|
||||
|
||||
Object.defineProperty(exports, 'urlencoded', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: createParserGetter('urlencoded')
|
||||
})
|
||||
|
||||
/**
|
||||
* Create a middleware to parse json and urlencoded bodies.
|
||||
*
|
||||
* @param {object} [options]
|
||||
* @return {function}
|
||||
* @deprecated
|
||||
* @public
|
||||
*/
|
||||
|
||||
function bodyParser (options) {
|
||||
// use default type for parsers
|
||||
var opts = Object.create(options || null, {
|
||||
type: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: undefined,
|
||||
writable: true
|
||||
}
|
||||
})
|
||||
|
||||
var _urlencoded = exports.urlencoded(opts)
|
||||
var _json = exports.json(opts)
|
||||
|
||||
return function bodyParser (req, res, next) {
|
||||
_json(req, res, function (err) {
|
||||
if (err) return next(err)
|
||||
_urlencoded(req, res, next)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a getter for loading a parser.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function createParserGetter (name) {
|
||||
return function get () {
|
||||
return loadParser(name)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a parser module.
|
||||
* @private
|
||||
*/
|
||||
|
||||
function loadParser (parserName) {
|
||||
var parser = parsers[parserName]
|
||||
|
||||
if (parser !== undefined) {
|
||||
return parser
|
||||
}
|
||||
|
||||
// this uses a switch for static require analysis
|
||||
switch (parserName) {
|
||||
case 'json':
|
||||
parser = require('./lib/types/json')
|
||||
break
|
||||
case 'raw':
|
||||
parser = require('./lib/types/raw')
|
||||
break
|
||||
case 'text':
|
||||
parser = require('./lib/types/text')
|
||||
break
|
||||
case 'urlencoded':
|
||||
parser = require('./lib/types/urlencoded')
|
||||
break
|
||||
}
|
||||
|
||||
// store to prevent invoking require()
|
||||
return (parsers[parserName] = parser)
|
||||
}
|
||||
205
labWeb/lab7/node_modules/body-parser/lib/read.js
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/*!
|
||||
* body-parser
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var createError = require('http-errors')
|
||||
var destroy = require('destroy')
|
||||
var getBody = require('raw-body')
|
||||
var iconv = require('iconv-lite')
|
||||
var onFinished = require('on-finished')
|
||||
var unpipe = require('unpipe')
|
||||
var zlib = require('zlib')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = read
|
||||
|
||||
/**
|
||||
* Read a request into a buffer and parse.
|
||||
*
|
||||
* @param {object} req
|
||||
* @param {object} res
|
||||
* @param {function} next
|
||||
* @param {function} parse
|
||||
* @param {function} debug
|
||||
* @param {object} options
|
||||
* @private
|
||||
*/
|
||||
|
||||
function read (req, res, next, parse, debug, options) {
|
||||
var length
|
||||
var opts = options
|
||||
var stream
|
||||
|
||||
// flag as parsed
|
||||
req._body = true
|
||||
|
||||
// read options
|
||||
var encoding = opts.encoding !== null
|
||||
? opts.encoding
|
||||
: null
|
||||
var verify = opts.verify
|
||||
|
||||
try {
|
||||
// get the content stream
|
||||
stream = contentstream(req, debug, opts.inflate)
|
||||
length = stream.length
|
||||
stream.length = undefined
|
||||
} catch (err) {
|
||||
return next(err)
|
||||
}
|
||||
|
||||
// set raw-body options
|
||||
opts.length = length
|
||||
opts.encoding = verify
|
||||
? null
|
||||
: encoding
|
||||
|
||||
// assert charset is supported
|
||||
if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
|
||||
return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
|
||||
charset: encoding.toLowerCase(),
|
||||
type: 'charset.unsupported'
|
||||
}))
|
||||
}
|
||||
|
||||
// read body
|
||||
debug('read body')
|
||||
getBody(stream, opts, function (error, body) {
|
||||
if (error) {
|
||||
var _error
|
||||
|
||||
if (error.type === 'encoding.unsupported') {
|
||||
// echo back charset
|
||||
_error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
|
||||
charset: encoding.toLowerCase(),
|
||||
type: 'charset.unsupported'
|
||||
})
|
||||
} else {
|
||||
// set status code on error
|
||||
_error = createError(400, error)
|
||||
}
|
||||
|
||||
// unpipe from stream and destroy
|
||||
if (stream !== req) {
|
||||
unpipe(req)
|
||||
destroy(stream, true)
|
||||
}
|
||||
|
||||
// read off entire request
|
||||
dump(req, function onfinished () {
|
||||
next(createError(400, _error))
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// verify
|
||||
if (verify) {
|
||||
try {
|
||||
debug('verify body')
|
||||
verify(req, res, body, encoding)
|
||||
} catch (err) {
|
||||
next(createError(403, err, {
|
||||
body: body,
|
||||
type: err.type || 'entity.verify.failed'
|
||||
}))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// parse
|
||||
var str = body
|
||||
try {
|
||||
debug('parse body')
|
||||
str = typeof body !== 'string' && encoding !== null
|
||||
? iconv.decode(body, encoding)
|
||||
: body
|
||||
req.body = parse(str)
|
||||
} catch (err) {
|
||||
next(createError(400, err, {
|
||||
body: str,
|
||||
type: err.type || 'entity.parse.failed'
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content stream of the request.
|
||||
*
|
||||
* @param {object} req
|
||||
* @param {function} debug
|
||||
* @param {boolean} [inflate=true]
|
||||
* @return {object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function contentstream (req, debug, inflate) {
|
||||
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
|
||||
var length = req.headers['content-length']
|
||||
var stream
|
||||
|
||||
debug('content-encoding "%s"', encoding)
|
||||
|
||||
if (inflate === false && encoding !== 'identity') {
|
||||
throw createError(415, 'content encoding unsupported', {
|
||||
encoding: encoding,
|
||||
type: 'encoding.unsupported'
|
||||
})
|
||||
}
|
||||
|
||||
switch (encoding) {
|
||||
case 'deflate':
|
||||
stream = zlib.createInflate()
|
||||
debug('inflate body')
|
||||
req.pipe(stream)
|
||||
break
|
||||
case 'gzip':
|
||||
stream = zlib.createGunzip()
|
||||
debug('gunzip body')
|
||||
req.pipe(stream)
|
||||
break
|
||||
case 'identity':
|
||||
stream = req
|
||||
stream.length = length
|
||||
break
|
||||
default:
|
||||
throw createError(415, 'unsupported content encoding "' + encoding + '"', {
|
||||
encoding: encoding,
|
||||
type: 'encoding.unsupported'
|
||||
})
|
||||
}
|
||||
|
||||
return stream
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the contents of a request.
|
||||
*
|
||||
* @param {object} req
|
||||
* @param {function} callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function dump (req, callback) {
|
||||
if (onFinished.isFinished(req)) {
|
||||
callback(null)
|
||||
} else {
|
||||
onFinished(req, callback)
|
||||
req.resume()
|
||||
}
|
||||
}
|
||||
247
labWeb/lab7/node_modules/body-parser/lib/types/json.js
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
/*!
|
||||
* body-parser
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2014-2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
* @private
|
||||
*/
|
||||
|
||||
var bytes = require('bytes')
|
||||
var contentType = require('content-type')
|
||||
var createError = require('http-errors')
|
||||
var debug = require('debug')('body-parser:json')
|
||||
var read = require('../read')
|
||||
var typeis = require('type-is')
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = json
|
||||
|
||||
/**
|
||||
* RegExp to match the first non-space in a string.
|
||||
*
|
||||
* Allowed whitespace is defined in RFC 7159:
|
||||
*
|
||||
* ws = *(
|
||||
* %x20 / ; Space
|
||||
* %x09 / ; Horizontal tab
|
||||
* %x0A / ; Line feed or New line
|
||||
* %x0D ) ; Carriage return
|
||||
*/
|
||||
|
||||
var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex
|
||||
|
||||
var JSON_SYNTAX_CHAR = '#'
|
||||
var JSON_SYNTAX_REGEXP = /#+/g
|
||||
|
||||
/**
|
||||
* Create a middleware to parse JSON bodies.
|
||||
*
|
||||
* @param {object} [options]
|
||||
* @return {function}
|
||||
* @public
|
||||
*/
|
||||
|
||||
function json (options) {
|
||||
var opts = options || {}
|
||||
|
||||
var limit = typeof opts.limit !== 'number'
|
||||
? bytes.parse(opts.limit || '100kb')
|
||||
: opts.limit
|
||||
var inflate = opts.inflate !== false
|
||||
var reviver = opts.reviver
|
||||
var strict = opts.strict !== false
|
||||
var type = opts.type || 'application/json'
|
||||
var verify = opts.verify || false
|
||||
|
||||
if (verify !== false && typeof verify !== 'function') {
|
||||
throw new TypeError('option verify must be function')
|
||||
}
|
||||
|
||||
// create the appropriate type checking function
|
||||
var shouldParse = typeof type !== 'function'
|
||||
? typeChecker(type)
|
||||
: type
|
||||
|
||||
function parse (body) {
|
||||
if (body.length === 0) {
|
||||
// special-case empty json body, as it's a common client-side mistake
|
||||
// TODO: maybe make this configurable or part of "strict" option
|
||||
return {}
|
||||
}
|
||||
|
||||
if (strict) {
|
||||
var first = firstchar(body)
|
||||
|
||||
if (first !== '{' && first !== '[') {
|
||||
debug('strict violation')
|
||||
throw createStrictSyntaxError(body, first)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
debug('parse json')
|
||||
return JSON.parse(body, reviver)
|
||||
} catch (e) {
|
||||
throw normalizeJsonSyntaxError(e, {
|
||||
message: e.message,
|
||||
stack: e.stack
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return function jsonParser (req, res, next) {
|
||||
if (req._body) {
|
||||
debug('body already parsed')
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
req.body = req.body || {}
|
||||
|
||||
// skip requests without bodies
|
||||
if (!typeis.hasBody(req)) {
|
||||
debug('skip empty body')
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
debug('content-type %j', req.headers['content-type'])
|
||||
|
||||
// determine if request should be parsed
|
||||
if (!shouldParse(req)) {
|
||||
debug('skip parsing')
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
// assert charset per RFC 7159 sec 8.1
|
||||
var charset = getCharset(req) || 'utf-8'
|
||||
if (charset.slice(0, 4) !== 'utf-') {
|
||||
debug('invalid charset')
|
||||
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
|
||||
charset: charset,
|
||||
type: 'charset.unsupported'
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
// read
|
||||
read(req, res, next, parse, debug, {
|
||||
encoding: charset,
|
||||
inflate: inflate,
|
||||
limit: limit,
|
||||
verify: verify
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create strict violation syntax error matching native error.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} char
|
||||
* @return {Error}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function createStrictSyntaxError (str, char) {
|
||||
var index = str.indexOf(char)
|
||||
var partial = ''
|
||||
|
||||
if (index !== -1) {
|
||||
partial = str.substring(0, index) + JSON_SYNTAX_CHAR
|
||||
|
||||
for (var i = index + 1; i < str.length; i++) {
|
||||
partial += JSON_SYNTAX_CHAR
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation')
|
||||
} catch (e) {
|
||||
return normalizeJsonSyntaxError(e, {
|
||||
message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) {
|
||||
return str.substring(index, index + placeholder.length)
|
||||
}),
|
||||
stack: e.stack
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first non-whitespace character in a string.
|
||||
*
|
||||
* @param {string} str
|
||||
* @return {function}
|
||||
* @private
|
||||
*/
|
||||
|
||||
function firstchar (str) {
|
||||
var match = FIRST_CHAR_REGEXP.exec(str)
|
||||
|
||||
return match
|
||||
? match[1]
|
||||
: undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the charset of a request.
|
||||
*
|
||||
* @param {object} req
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function getCharset (req) {
|
||||
try {
|
||||
return (contentType.parse(req).parameters.charset || '').toLowerCase()
|
||||
} catch (e) {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a SyntaxError for JSON.parse.
|
||||
*
|
||||
* @param {SyntaxError} error
|
||||
* @param {object} obj
|
||||
* @return {SyntaxError}
|
||||
*/
|
||||
|
||||
function normalizeJsonSyntaxError (error, obj) {
|
||||
var keys = Object.getOwnPropertyNames(error)
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i]
|
||||
if (key !== 'stack' && key !== 'message') {
|
||||
delete error[key]
|
||||
}
|
||||
}
|
||||
|
||||
// replace stack before message for Node.js 0.10 and below
|
||||
error.stack = obj.stack.replace(error.message, obj.message)
|
||||
error.message = obj.message
|
||||
|
||||
return error
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the simple type checker.
|
||||
*
|
||||
* @param {string} type
|
||||
* @return {function}
|
||||
*/
|
||||
|
||||
function typeChecker (type) {
|
||||
return function checkType (req) {
|
||||
return Boolean(typeis(req, type))
|
||||
}
|
||||
}
|
||||