From d90389cfbe8edbcb4ad42beebe13e5ee43288a30 Mon Sep 17 00:00:00 2001
From: AnnZhimol <ankavanka731@gmail.com>
Date: Sun, 19 Mar 2023 22:43:59 +0400
Subject: [PATCH] Lab 3

---
 Front/index.html                              |  54 --
 Front/main.js                                 |  39 -
 Front/package-lock.json                       | 803 ------------------
 Front/package.json                            |  18 -
 build.gradle                                  |   4 +
 .../java/ru/ulstu/is/cbapp/ConfigWeb.java     |  13 -
 .../Lab2/controller/ControllerCalculate.java  |  42 -
 .../ulstu/is/cbapp/Lab2/domain/Calculate.java |   8 -
 .../ru/ulstu/is/cbapp/Lab2/domain/Errors.java |  11 -
 .../cbapp/Lab2/domain/IntegerCalculate.java   |  29 -
 .../is/cbapp/Lab2/domain/ReturnObject.java    |   8 -
 .../is/cbapp/Lab2/domain/StringCalculate.java |  27 -
 .../cbapp/Lab2/service/ServiceCalculate.java  |  85 --
 .../ru/ulstu/is/cbapp/models/Category.java    |  73 ++
 .../ulstu/is/cbapp/models/DrivingSchool.java  |  83 ++
 .../ru/ulstu/is/cbapp/models/Student.java     | 109 +++
 .../is/cbapp/service/CategoryService.java     |  67 ++
 .../cbapp/service/DrivingSchoolService.java   |  91 ++
 .../is/cbapp/service/StudentService.java      | 100 +++
 src/main/resources/application.properties     |  12 +-
 .../ulstu/is/cbapp/CategoryServiceTests.java  |  55 ++
 .../ulstu/is/cbapp/CbappApplicationTests.java |  52 --
 .../is/cbapp/DrivingSchoolServiceTests.java   | 118 +++
 .../ulstu/is/cbapp/StudentServiceTests.java   |  92 ++
 24 files changed, 803 insertions(+), 1190 deletions(-)
 delete mode 100644 Front/index.html
 delete mode 100644 Front/main.js
 delete mode 100644 Front/package-lock.json
 delete mode 100644 Front/package.json
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/ConfigWeb.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/controller/ControllerCalculate.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Calculate.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Errors.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/domain/IntegerCalculate.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/domain/ReturnObject.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/domain/StringCalculate.java
 delete mode 100644 src/main/java/ru/ulstu/is/cbapp/Lab2/service/ServiceCalculate.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/models/Category.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/models/DrivingSchool.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/models/Student.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/service/CategoryService.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/service/DrivingSchoolService.java
 create mode 100644 src/main/java/ru/ulstu/is/cbapp/service/StudentService.java
 create mode 100644 src/test/java/ru/ulstu/is/cbapp/CategoryServiceTests.java
 delete mode 100644 src/test/java/ru/ulstu/is/cbapp/CbappApplicationTests.java
 create mode 100644 src/test/java/ru/ulstu/is/cbapp/DrivingSchoolServiceTests.java
 create mode 100644 src/test/java/ru/ulstu/is/cbapp/StudentServiceTests.java

diff --git a/Front/index.html b/Front/index.html
deleted file mode 100644
index 952c990..0000000
--- a/Front/index.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE html>
-
-<html lang="ru">
-
-<head>
-  <title>Лабораторная №2</title>
-  <meta charset="utf-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
-  <script src="node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
-  <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
-  <script src="main.js"></script>
-</head>
-
-<body>
-  <article class="d-flex">
-    <div class="d-flex flex-column align-items-start">
-      <div class="m-3">
-        <label class="form-label">Операция</label>
-        <select class="form-select form-select-lg" id="operation" onchange="changeVariableInputs()">
-          <option disabled>Выберите операцию</option>
-          <option value="sum">Сложение</option>
-          <option value="sut">Вычитание</option>
-          <option value="len">Подсчёт длины</option>
-          <option value="inv">Инверсия (Отрицание)</option>
-        </select>
-        <div class="mb-3">
-          <label class="form-label">Введите переменнную А</label>
-          <input type="number" class="form-control" id="var_a">
-        </div>
-        <button type="button" class="btn btn-primary mx-3" onclick="calculate()">Подтвердить</button>
-      </div>
-    </div>
-    <div class="d-flex flex-column align-items-start m-3">
-      <div class="m-3 mt-0">
-        <label class="form-label">Тип переменной</label>
-        <select class="form-select form-select-lg" id="valueType" onchange="changeInputBoxType()">
-          <option disabled>Выберите тип</option>
-          <option value="number">Число</option>
-          <option value="string">Строка</option>
-        </select>
-        <div class="mb-3" id="InputFieldB">
-          <label class="form-label">Введите переменнную В</label>
-          <input type="number" class="form-control" id="var_b">
-        </div>
-        <div class="d-flex align-items-center mx-3">
-          <H1 id="ansver">Результат:</h1>
-        </div>
-      </div>
-    </div>
-  </article>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/Front/main.js b/Front/main.js
deleted file mode 100644
index 48c509c..0000000
--- a/Front/main.js
+++ /dev/null
@@ -1,39 +0,0 @@
-async function calculate(){
-    const valA = document.getElementById("var_a").value
-    const valB = document.getElementById("var_b").value
-    const oper = document.getElementById("operation").value
-    const type = document.getElementById("valueType").value
-
-    var url = `http://localhost:8080/${oper}?type=${type}&a=${valA}&b=${valB}`
-
-    console.log(url)
-    const responce = await fetch(url)
-    const json = await responce.json()
-    if(json.content.errorCode != null){
-        document.getElementById("ansver").innerHTML = "Ошибка: "+ json.content.errorMassage;
-    }
-    else{
-        document.getElementById("ansver").innerHTML = "Ответ: "+ json.content
-    }
-}
-function changeVariableInputs(){
-    const oper = document.getElementById("operation").value
-
-    if(oper === "len" || oper === "inv"){
-        document.getElementById("InputFieldB").classList.add("hide")
-    }
-    else{
-        document.getElementById("InputFieldB").classList.remove("hide")
-    }
-}
-function changeInputBoxType(){
-    const type = document.getElementById("valueType").value
-    if(type === "number"){
-        document.getElementById("var_a").type = "number"
-        document.getElementById("var_b").type = "number"
-    }
-    else{
-        document.getElementById("var_a").type = "text"
-        document.getElementById("var_b").type = "text"
-    }
-}
\ No newline at end of file
diff --git a/Front/package-lock.json b/Front/package-lock.json
deleted file mode 100644
index 02e9b3d..0000000
--- a/Front/package-lock.json
+++ /dev/null
@@ -1,803 +0,0 @@
-{
-  "name": "frontend",
-  "version": "1.0.0",
-  "lockfileVersion": 2,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "frontend",
-      "version": "1.0.0",
-      "license": "ISC",
-      "dependencies": {
-        "bootstrap": "^5.2.3"
-      },
-      "devDependencies": {
-        "http-server": "14.1.1"
-      }
-    },
-    "node_modules/@popperjs/core": {
-      "version": "2.11.6",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
-      "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
-      "peer": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/popperjs"
-      }
-    },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/async": {
-      "version": "2.6.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
-      "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
-      "dev": true,
-      "dependencies": {
-        "lodash": "^4.17.14"
-      }
-    },
-    "node_modules/basic-auth": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
-      "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "5.1.2"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/bootstrap": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
-      "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/twbs"
-        },
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/bootstrap"
-        }
-      ],
-      "peerDependencies": {
-        "@popperjs/core": "^2.11.6"
-      }
-    },
-    "node_modules/call-bind": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "node_modules/corser": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
-      "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/debug": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/eventemitter3": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
-      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
-      "dev": true
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "node_modules/get-intrinsic": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
-      "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true,
-      "bin": {
-        "he": "bin/he"
-      }
-    },
-    "node_modules/html-encoding-sniffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
-      "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
-      "dev": true,
-      "dependencies": {
-        "whatwg-encoding": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/http-proxy": {
-      "version": "1.18.1",
-      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
-      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
-      "dev": true,
-      "dependencies": {
-        "eventemitter3": "^4.0.0",
-        "follow-redirects": "^1.0.0",
-        "requires-port": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/http-server": {
-      "version": "14.1.1",
-      "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
-      "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
-      "dev": true,
-      "dependencies": {
-        "basic-auth": "^2.0.1",
-        "chalk": "^4.1.2",
-        "corser": "^2.0.1",
-        "he": "^1.2.0",
-        "html-encoding-sniffer": "^3.0.0",
-        "http-proxy": "^1.18.1",
-        "mime": "^1.6.0",
-        "minimist": "^1.2.6",
-        "opener": "^1.5.1",
-        "portfinder": "^1.0.28",
-        "secure-compare": "3.0.1",
-        "union": "~0.5.0",
-        "url-join": "^4.0.1"
-      },
-      "bin": {
-        "http-server": "bin/http-server"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/iconv-lite": {
-      "version": "0.6.3",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-      "dev": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
-    },
-    "node_modules/mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "dev": true,
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
-      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/mkdirp": {
-      "version": "0.5.6",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
-      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.6"
-      },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "dev": true
-    },
-    "node_modules/object-inspect": {
-      "version": "1.12.3",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
-      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/opener": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
-      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
-      "dev": true,
-      "bin": {
-        "opener": "bin/opener-bin.js"
-      }
-    },
-    "node_modules/portfinder": {
-      "version": "1.0.32",
-      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
-      "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
-      "dev": true,
-      "dependencies": {
-        "async": "^2.6.4",
-        "debug": "^3.2.7",
-        "mkdirp": "^0.5.6"
-      },
-      "engines": {
-        "node": ">= 0.12.0"
-      }
-    },
-    "node_modules/qs": {
-      "version": "6.11.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
-      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
-      "dev": true,
-      "dependencies": {
-        "side-channel": "^1.0.4"
-      },
-      "engines": {
-        "node": ">=0.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
-      "dev": true
-    },
-    "node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
-    },
-    "node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "node_modules/secure-compare": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
-      "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
-      "dev": true
-    },
-    "node_modules/side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/union": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
-      "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
-      "dev": true,
-      "dependencies": {
-        "qs": "^6.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
-    "node_modules/url-join": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
-      "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
-      "dev": true
-    },
-    "node_modules/whatwg-encoding": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
-      "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
-      "dev": true,
-      "dependencies": {
-        "iconv-lite": "0.6.3"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    }
-  },
-  "dependencies": {
-    "@popperjs/core": {
-      "version": "2.11.6",
-      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
-      "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
-      "peer": true
-    },
-    "ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "requires": {
-        "color-convert": "^2.0.1"
-      }
-    },
-    "async": {
-      "version": "2.6.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
-      "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
-      "dev": true,
-      "requires": {
-        "lodash": "^4.17.14"
-      }
-    },
-    "basic-auth": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
-      "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "5.1.2"
-      }
-    },
-    "bootstrap": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
-      "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
-      "requires": {}
-    },
-    "call-bind": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
-      }
-    },
-    "chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      }
-    },
-    "color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "requires": {
-        "color-name": "~1.1.4"
-      }
-    },
-    "color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "corser": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
-      "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
-      "dev": true
-    },
-    "debug": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-      "dev": true,
-      "requires": {
-        "ms": "^2.1.1"
-      }
-    },
-    "eventemitter3": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
-      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
-      "dev": true
-    },
-    "follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true
-    },
-    "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "get-intrinsic": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
-      "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.3"
-      }
-    },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1"
-      }
-    },
-    "has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true
-    },
-    "has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "dev": true
-    },
-    "he": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
-      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true
-    },
-    "html-encoding-sniffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
-      "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
-      "dev": true,
-      "requires": {
-        "whatwg-encoding": "^2.0.0"
-      }
-    },
-    "http-proxy": {
-      "version": "1.18.1",
-      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
-      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
-      "dev": true,
-      "requires": {
-        "eventemitter3": "^4.0.0",
-        "follow-redirects": "^1.0.0",
-        "requires-port": "^1.0.0"
-      }
-    },
-    "http-server": {
-      "version": "14.1.1",
-      "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
-      "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
-      "dev": true,
-      "requires": {
-        "basic-auth": "^2.0.1",
-        "chalk": "^4.1.2",
-        "corser": "^2.0.1",
-        "he": "^1.2.0",
-        "html-encoding-sniffer": "^3.0.0",
-        "http-proxy": "^1.18.1",
-        "mime": "^1.6.0",
-        "minimist": "^1.2.6",
-        "opener": "^1.5.1",
-        "portfinder": "^1.0.28",
-        "secure-compare": "3.0.1",
-        "union": "~0.5.0",
-        "url-join": "^4.0.1"
-      }
-    },
-    "iconv-lite": {
-      "version": "0.6.3",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
-      "dev": true,
-      "requires": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      }
-    },
-    "lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
-    },
-    "mime": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-      "dev": true
-    },
-    "minimist": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
-      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "dev": true
-    },
-    "mkdirp": {
-      "version": "0.5.6",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
-      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
-      "dev": true,
-      "requires": {
-        "minimist": "^1.2.6"
-      }
-    },
-    "ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "dev": true
-    },
-    "object-inspect": {
-      "version": "1.12.3",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
-      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
-      "dev": true
-    },
-    "opener": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
-      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
-      "dev": true
-    },
-    "portfinder": {
-      "version": "1.0.32",
-      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
-      "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
-      "dev": true,
-      "requires": {
-        "async": "^2.6.4",
-        "debug": "^3.2.7",
-        "mkdirp": "^0.5.6"
-      }
-    },
-    "qs": {
-      "version": "6.11.0",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
-      "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
-      "dev": true,
-      "requires": {
-        "side-channel": "^1.0.4"
-      }
-    },
-    "requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
-      "dev": true
-    },
-    "safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
-    },
-    "safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "secure-compare": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
-      "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
-      "dev": true
-    },
-    "side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
-      }
-    },
-    "supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "requires": {
-        "has-flag": "^4.0.0"
-      }
-    },
-    "union": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
-      "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
-      "dev": true,
-      "requires": {
-        "qs": "^6.4.0"
-      }
-    },
-    "url-join": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
-      "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
-      "dev": true
-    },
-    "whatwg-encoding": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
-      "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
-      "dev": true,
-      "requires": {
-        "iconv-lite": "0.6.3"
-      }
-    }
-  }
-}
diff --git a/Front/package.json b/Front/package.json
deleted file mode 100644
index f9fc905..0000000
--- a/Front/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "frontend",
-  "version": "1.0.0",
-  "description": "",
-  "main": "index.html",
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1",
-    "start": "http-server -p 3000 ./"
-  },
-  "author": "",
-  "license": "ISC",
-  "dependencies": {
-    "bootstrap": "^5.2.3"
-  },
-  "devDependencies": {
-    "http-server": "14.1.1"
-  }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 40bbb42..05772a0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,6 +14,10 @@ repositories {
 
 dependencies {
 	implementation 'org.springframework.boot:spring-boot-starter-web'
+
+	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+	implementation 'com.h2database:h2:2.1.210'
+
 	testImplementation 'org.springframework.boot:spring-boot-starter-test'
 }
 
diff --git a/src/main/java/ru/ulstu/is/cbapp/ConfigWeb.java b/src/main/java/ru/ulstu/is/cbapp/ConfigWeb.java
deleted file mode 100644
index 7dc25fd..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/ConfigWeb.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.ulstu.is.cbapp;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-@Configuration
-public class ConfigWeb implements WebMvcConfigurer {
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**").allowedMethods("*");
-    }
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/controller/ControllerCalculate.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/controller/ControllerCalculate.java
deleted file mode 100644
index a8828a3..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/controller/ControllerCalculate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.controller;
-import org.springframework.web.bind.annotation.*;
-
-import ru.ulstu.is.cbapp.Lab2.domain.ReturnObject;
-import ru.ulstu.is.cbapp.Lab2.service.ServiceCalculate;
-
-@RestController
-@CrossOrigin
-public class ControllerCalculate {
-    private final ServiceCalculate serviceCalculate;
-
-    public ControllerCalculate(ServiceCalculate serviceCalculate){
-        this.serviceCalculate=serviceCalculate;
-    }
-
-    @GetMapping("/sum")
-    public ReturnObject sum(@RequestParam(value = "type",defaultValue = "number") String type,
-                            @RequestParam(value = "a", required = false) String a,
-                            @RequestParam(value = "b", required = false) String b){
-        return new ReturnObject(serviceCalculate.add(a,b,type));
-    }
-
-    @GetMapping("/sut")
-    public ReturnObject sut(@RequestParam(value = "type",defaultValue = "number") String type,
-                            @RequestParam(value = "a", required = false) String a,
-                            @RequestParam(value = "b", required = false) String b){
-        return new ReturnObject(serviceCalculate.sut(a,b,type));
-    }
-
-    @GetMapping("/len")
-    public ReturnObject len(@RequestParam(value = "type",required = false) String type,
-                            @RequestParam(value = "a", required = false) String a){
-        return new ReturnObject(serviceCalculate.len(a,type));
-    }
-
-    @GetMapping("/inv")
-    public ReturnObject inv(@RequestParam(value = "type",defaultValue = "number") String type,
-                            @RequestParam(value = "a", defaultValue = "0") String a){
-        return new ReturnObject(serviceCalculate.inv(a,type));
-    }
-
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Calculate.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Calculate.java
deleted file mode 100644
index 537e3f5..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Calculate.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.domain;
-
-public interface Calculate<T> {
-    T add(T a, T b);
-    T sut(T a, T b);
-    Integer len(T a);
-    T inv(T a);
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Errors.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Errors.java
deleted file mode 100644
index 3d2cc7b..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/Errors.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.domain;
-
-public class Errors {
-    public Integer errorCode;
-    public String errorMassage;
-
-    public Errors(Integer code, String massage){
-        this.errorCode = code;
-        this.errorMassage = massage;
-    }
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/IntegerCalculate.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/IntegerCalculate.java
deleted file mode 100644
index 5bae44b..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/IntegerCalculate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.domain;
-
-import org.springframework.stereotype.Component;
-
-@Component(value="number")
-public class IntegerCalculate implements Calculate<Integer> {
-
-    @Override
-    public Integer add(Integer a, Integer b) {
-        return a + b;
-    }
-
-    @Override
-    public Integer sut(Integer a, Integer b) {
-        return a - b;
-    }
-
-    @Override
-    public Integer len(Integer a) {
-        Integer length = String.valueOf(a).length();
-        return length;
-    }
-
-    @Override
-    public Integer inv(Integer a) {
-        return -a;
-    }
-
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/ReturnObject.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/ReturnObject.java
deleted file mode 100644
index 9e68c57..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/ReturnObject.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.domain;
-public class ReturnObject {
-    public Object content;
-
-    public ReturnObject(Object content){
-        this.content = content;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/StringCalculate.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/StringCalculate.java
deleted file mode 100644
index 02361f2..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/domain/StringCalculate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.domain;
-
-import org.springframework.stereotype.Component;
-
-@Component(value = "string")
-public class StringCalculate implements Calculate<String> {
-
-    @Override
-    public String add(String a, String b) {
-        return a+b;
-    }
-
-    @Override
-    public String sut(String a, String b) {
-        return a.replace(b, "");
-    }
-
-    @Override
-    public Integer len(String a) {
-        return a.length();
-    }
-
-    @Override
-    public String inv(String a) {
-        return new StringBuilder(a).reverse().toString();
-    }
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/Lab2/service/ServiceCalculate.java b/src/main/java/ru/ulstu/is/cbapp/Lab2/service/ServiceCalculate.java
deleted file mode 100644
index 56d41dc..0000000
--- a/src/main/java/ru/ulstu/is/cbapp/Lab2/service/ServiceCalculate.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package ru.ulstu.is.cbapp.Lab2.service;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
-import ru.ulstu.is.cbapp.Lab2.domain.Calculate;
-import ru.ulstu.is.cbapp.Lab2.domain.Errors;
-
-@Service
-public class ServiceCalculate {
-    private final ApplicationContext applicationContext;
-
-    public ServiceCalculate(ApplicationContext applicationContext) {
-        this.applicationContext = applicationContext;
-    }
-
-    public Object add(Object a, Object b, String type){
-        Calculate calculate = (Calculate) applicationContext.getBean(type);
-        if (!StringUtils.hasText(a.toString()) || !StringUtils.hasText(b.toString())){
-            return new Errors(400, "Необходимо заполенение обоих полей");
-        }
-        try {
-            if(type.equals("number")){
-
-                a = castToInt(a);
-                b = castToInt(b);
-            }
-            return calculate.add(a,b);
-        }
-        catch (Exception ex){
-            return new Errors(400, ex.getMessage());
-        }
-    }
-
-    public Object sut(Object a, Object b, String type){
-        Calculate calculate = (Calculate)applicationContext.getBean(type);
-        if (a==null || a.equals("") || b==null || b.equals("")){
-            return new Errors(400, "Необходимо заполенение обоих полей");
-        }
-        try {
-            if(type.equals("number")){
-                a = castToInt(a);
-                b = castToInt(b);
-            }
-            return calculate.sut(a,b);
-        }
-        catch (Exception ex){
-            return new Errors(400, ex.getMessage());
-        }
-    }
-    public Object len(Object a, String type){
-        Calculate calculate = (Calculate)applicationContext.getBean(type);
-        if (a==null || a.equals("")){
-            return new Errors(400, "Необходимо заполенение переменной");
-        }
-        try {
-            if(type.equals("number")){
-                a = castToInt(a);
-            }
-            return calculate.len(a);
-        }
-        catch (Exception ex){
-            return new Errors(400, ex.getMessage());
-        }
-    }
-    public Object inv(Object a, String type){
-        Calculate calculate = (Calculate)applicationContext.getBean(type);
-        if (a==null || a.equals("")){
-            return new Errors(400, "Необходимо заполенение переменной");
-        }
-        try {
-            if(type.equals("number")){
-                a = castToInt(a);
-            }
-            return calculate.inv(a);
-        }
-        catch (Exception ex){
-            return new Errors(400, ex.getMessage());
-        }
-    }
-    public Object castToInt(Object a){
-        return Integer.parseInt(a.toString());
-    }
-
-}
diff --git a/src/main/java/ru/ulstu/is/cbapp/models/Category.java b/src/main/java/ru/ulstu/is/cbapp/models/Category.java
new file mode 100644
index 0000000..3c29a1b
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/models/Category.java
@@ -0,0 +1,73 @@
+package ru.ulstu.is.cbapp.models;
+
+import javax.persistence.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Entity
+public class Category {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long Id;
+
+    private String name;
+
+    //mappedBy - атрибут, указывающий, что классом-владельцем отношений является другой класс
+    @ManyToMany(mappedBy = "categories", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    private List<Student> students = new ArrayList<>();
+
+    public Category() {
+    }
+
+    public Category(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Long getId() {
+        return Id;
+    }
+
+    public List<Student> getStudents() {
+        return students;
+    }
+
+    public void setStudents(List<Student> students) {
+        this.students = students;
+    }
+
+    public void addNewStudent(Student e) {
+        students.add(e);
+        if (!e.getCategories().contains(this)) {
+            e.addNewCategory(this);
+        }
+    }
+    public void deleteStudent(Student e) {
+        students.remove(e);
+        if (e.getCategories().contains(this)) {
+            e.removeCategory(this);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Category student = (Category) o;
+        return Objects.equals(Id, student.Id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(Id);
+    }
+}
diff --git a/src/main/java/ru/ulstu/is/cbapp/models/DrivingSchool.java b/src/main/java/ru/ulstu/is/cbapp/models/DrivingSchool.java
new file mode 100644
index 0000000..b6bbca3
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/models/DrivingSchool.java
@@ -0,0 +1,83 @@
+package ru.ulstu.is.cbapp.models;
+
+import javax.persistence.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@Entity
+public class DrivingSchool {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long Id;
+    @Column(unique = true)
+    private String name;
+    @OneToMany(mappedBy = "drivingSchool", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    private List<Student> students = new ArrayList<>();
+
+    public DrivingSchool(String name, List<Student> students) {
+        this.name = name;
+        this.students = students;
+    }
+
+    public DrivingSchool(String name) {
+        this.name = name;
+    }
+
+    public DrivingSchool() {
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void addNewStudent(Student student) {
+        students.add(student);
+        student.setDrivingSchool(this);
+    }
+
+    public void deleteStudent(Student student) {
+        students.remove(student);
+        student.deleteDrivingSchool();
+
+    }
+
+    public Long getId() {
+        return Id;
+    }
+
+    public List<Student> getStudents() {
+        return students;
+    }
+
+    public void setStudents(List<Student> students) {
+        this.students = students;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DrivingSchool drivingSchool = (DrivingSchool) o;
+        return Objects.equals(Id, drivingSchool.Id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(Id);
+    }
+
+    @Override
+    public String toString() {
+        return "DrivingSchool{" +
+                "Id=" + Id +
+                ", name='" + name + '\'' +
+                ", students=" + students +
+                '}';
+    }
+}
diff --git a/src/main/java/ru/ulstu/is/cbapp/models/Student.java b/src/main/java/ru/ulstu/is/cbapp/models/Student.java
new file mode 100644
index 0000000..5e39ad9
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/models/Student.java
@@ -0,0 +1,109 @@
+package ru.ulstu.is.cbapp.models;
+
+import javax.persistence.*;
+
+import java.util.*;
+
+@Entity
+public class Student {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+    private String phoneNumber;
+    private String name;
+    private String surname;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private DrivingSchool drivingSchool;
+
+    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+    private Set<Category> categories = new HashSet<>();
+
+
+    public Student(String phoneNumber, String name, String surname) {
+        this.phoneNumber = phoneNumber;
+        this.name = name;
+        this.surname = surname;
+    }
+
+    public Student() {
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getPhoneNumber() {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber) {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getSurname() {
+        return surname;
+    }
+
+    public void setSurname(String surname) {
+        this.surname = surname;
+    }
+
+    public List<Category> getCategories() {
+        return categories.stream().toList();
+    }
+
+    public DrivingSchool getDrivingSchool() {
+        return drivingSchool;
+    }
+
+    public void setDrivingSchool(DrivingSchool drivingSchool) {
+        this.drivingSchool = drivingSchool;
+        if (!drivingSchool.getStudents().contains(this)) {
+            drivingSchool.addNewStudent(this);
+        }
+    }
+
+    public void deleteDrivingSchool() {
+        if (drivingSchool.getStudents().contains(this)) {
+            drivingSchool.deleteStudent(this);
+        }
+        this.drivingSchool = null;
+    }
+
+    public void addNewCategory(Category p) {
+        categories.add(p);
+        if (!p.getStudents().contains(this)) {
+            p.addNewStudent(this);
+        }
+
+    }
+
+    public void removeCategory(Category p) {
+        categories.remove(p);
+        if (p.getStudents().contains(this)) {
+            p.deleteStudent(this);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Student e = (Student) o;
+        return Objects.equals(id, e.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}
diff --git a/src/main/java/ru/ulstu/is/cbapp/service/CategoryService.java b/src/main/java/ru/ulstu/is/cbapp/service/CategoryService.java
new file mode 100644
index 0000000..60aa45a
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/service/CategoryService.java
@@ -0,0 +1,67 @@
+package ru.ulstu.is.cbapp.service;
+
+import ru.ulstu.is.cbapp.models.Category;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.PersistenceContext;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+@Service
+public class CategoryService {
+    @PersistenceContext
+    private EntityManager em;
+
+    @Transactional
+    public Category addCategory(String name) {
+        if (!StringUtils.hasText(name)) {
+            throw new IllegalArgumentException("Student's data is null or empty");
+        }
+        final Category category = new Category(name);
+        em.persist(category);
+        return category;
+    }
+
+    @Transactional
+    public Category findCategory(Long id) {
+        final Category category = em.find(Category.class, id);
+        if (category == null) {
+            throw new EntityNotFoundException(String.format("Category with id [%s] is not found", id));
+        }
+        return category;
+    }
+
+    @Transactional(readOnly = true)
+    public List<Category> findAllCategories() {
+        return em.createQuery("select p from Category p", Category.class)
+                .getResultList();
+    }
+
+    @Transactional
+    public Category updateCategory(Long id, String surname, String name, String phoneNumber) {
+        if (!StringUtils.hasText(name) ||!StringUtils.hasText(surname) || !StringUtils.hasText(phoneNumber)) {
+            throw new IllegalArgumentException("Student's data is null or empty");
+        }
+        final Category currentCategory = findCategory(id);
+        currentCategory.setName(name);
+
+        return em.merge(currentCategory);
+    }
+
+    @Transactional
+    public Category deleteCategory(Long id) {
+        final Category p = findCategory(id);
+        em.remove(p);
+        return p;
+    }
+
+    @Transactional
+    public void deleteAllCategories() {
+        em.createQuery("delete from Category").executeUpdate();
+    }
+
+
+}
diff --git a/src/main/java/ru/ulstu/is/cbapp/service/DrivingSchoolService.java b/src/main/java/ru/ulstu/is/cbapp/service/DrivingSchoolService.java
new file mode 100644
index 0000000..f2b80b9
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/service/DrivingSchoolService.java
@@ -0,0 +1,91 @@
+package ru.ulstu.is.cbapp.service;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.PersistenceContext;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import ru.ulstu.is.cbapp.models.DrivingSchool;
+import ru.ulstu.is.cbapp.models.Student;
+
+import java.util.List;
+
+@Service
+public class DrivingSchoolService {
+    @PersistenceContext
+    private EntityManager em;
+
+    @Transactional
+    public DrivingSchool addDrivingSchool(String name) {
+        if (!StringUtils.hasText(name)) {
+            throw new IllegalArgumentException("Student name is null or empty");
+        }
+        final DrivingSchool drivingSchool = new DrivingSchool(name);
+        em.persist(drivingSchool);
+        return drivingSchool;
+    }
+
+    @Transactional(readOnly = true)
+    public DrivingSchool findDrivingSchool(Long id) {
+        final DrivingSchool drivingSchool = em.find(DrivingSchool.class, id);
+        if (drivingSchool == null) {
+            throw new EntityNotFoundException(String.format("DrivingSchool with id [%s] is not found", id));
+        }
+        return drivingSchool;
+    }
+
+    @Transactional(readOnly = true)
+    public DrivingSchool findDrivingSchool(String name) {
+        DrivingSchool drivingSchool = em.createQuery("select d from DrivingSchool d WHERE d.name = :drivingSchoolName", DrivingSchool.class)
+                .setParameter("drivingSchoolName",name)
+                .getSingleResult();
+        if (drivingSchool == null) {
+            throw new EntityNotFoundException(String.format("DrivingSchool with name [%s] is not found", name));
+        }
+        return drivingSchool;
+    }
+
+    @Transactional(readOnly = true)
+    public List<DrivingSchool> findAllDrivingSchools() {
+        return em.createQuery("select d from DrivingSchool d", DrivingSchool.class)
+                .getResultList();
+    }
+
+    @Transactional
+    public DrivingSchool updateDrivingSchool(Long id, String name) {
+        if (!StringUtils.hasText(name)) {
+            throw new IllegalArgumentException("DrivingSchool name is null or empty");
+        }
+        final DrivingSchool currentDrivingSchool = findDrivingSchool(id);
+        currentDrivingSchool.setName(name);
+
+        return em.merge(currentDrivingSchool);
+    }
+
+    @Transactional
+    public DrivingSchool deleteDrivingSchool(Long id) {
+        final DrivingSchool currentDrivingSchool = findDrivingSchool(id);
+        em.remove(currentDrivingSchool);
+        return currentDrivingSchool;
+    }
+
+    @Transactional
+    public void deleteAllDrivingSchools() {
+        em.createQuery("delete from DrivingSchool").executeUpdate();
+    }
+
+    @Transactional
+    public void addNewStudent(Long id, Student student) {
+        DrivingSchool currentDrivingSchool = findDrivingSchool(id);
+        currentDrivingSchool.addNewStudent(student);
+        em.merge(currentDrivingSchool);
+    }
+
+    @Transactional
+    public void deleteStudent(Long id, Student student) {
+        DrivingSchool currentDrivingSchool = findDrivingSchool(id);
+        currentDrivingSchool.deleteStudent(student);
+        em.merge(student);
+    }
+}
diff --git a/src/main/java/ru/ulstu/is/cbapp/service/StudentService.java b/src/main/java/ru/ulstu/is/cbapp/service/StudentService.java
new file mode 100644
index 0000000..e971eae
--- /dev/null
+++ b/src/main/java/ru/ulstu/is/cbapp/service/StudentService.java
@@ -0,0 +1,100 @@
+package ru.ulstu.is.cbapp.service;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.PersistenceContext;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+import ru.ulstu.is.cbapp.models.DrivingSchool;
+import ru.ulstu.is.cbapp.models.Student;
+import ru.ulstu.is.cbapp.models.Category;
+
+import java.util.List;
+
+@Service
+public class StudentService {
+    @PersistenceContext
+    private EntityManager em;
+
+    @Transactional
+    public Student addStudent(String surname, String name, String phoneNumber) {
+        if (!StringUtils.hasText(name) ||!StringUtils.hasText(surname) || !StringUtils.hasText(phoneNumber)) {
+            throw new IllegalArgumentException("Student's data is null or empty");
+        }
+        final Student student = new Student(surname, name, phoneNumber);
+        em.persist(student);
+        return student;
+    }
+
+    @Transactional
+    public Student findStudent(Long id) {
+        final Student student = em.find(Student.class, id);
+        if (student == null) {
+            throw new EntityNotFoundException(String.format("Student with id [%s] is not found", id));
+        }
+        return student;
+    }
+
+    @Transactional(readOnly = true)
+    public List<Student> findAllStudents() {
+        return em.createQuery("select e from Student e", Student.class)
+                .getResultList();
+    }
+
+    @Transactional
+    public Student updateDrivingSchool(Long id, String surname, String name, String phoneNumber) {
+        if (!StringUtils.hasText(name) ||!StringUtils.hasText(surname) || !StringUtils.hasText(phoneNumber)) {
+            throw new IllegalArgumentException("Student's data is null or empty");
+        }
+        final Student currentStudent = findStudent(id);
+        currentStudent.setName(name);
+        currentStudent.setSurname(surname);
+        currentStudent.setPhoneNumber(phoneNumber);
+
+        return em.merge(currentStudent);
+    }
+
+    @Transactional
+    public Student deleteStudent(Long id) {
+        final Student student = findStudent(id);
+        em.remove(student);
+        return student;
+    }
+
+    @Transactional
+    public void deleteAllStudents() {
+        em.createQuery("delete from Student").executeUpdate();
+    }
+
+    @Transactional
+    public void addDrivingSchool(Long id, DrivingSchool d) {
+        final Student student = findStudent(id);
+        student.setDrivingSchool(d);
+        em.merge(student);
+    }
+
+    @Transactional
+    public void deleteDrivingSchool(Long id) {
+        final Student student = findStudent(id);
+        student.deleteDrivingSchool();
+        em.merge(student);
+    }
+
+    @Transactional
+    public void addCategory(Long id, Category p) {
+        Student e = findStudent(id);
+        e.addNewCategory(p);
+        System.out.println(e.getCategories().size());
+        em.merge(e);
+    }
+
+    @Transactional
+    public void deleteCategory(Long id, Category p) {
+        Student e = findStudent(id);
+        e.removeCategory(p);
+        System.out.println("Количество должностей после удаления: " + e.getCategories().size());
+        em.merge(e);
+        em.flush();
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8b13789..da7b0b1 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,11 @@
-
+spring.main.banner-mode=off
+#server.port=8080
+spring.datasource.url=jdbc:h2:file:./data
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
+spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
+spring.jpa.hibernate.ddl-auto=update
+spring.h2.console.enabled=true
+spring.h2.console.settings.trace=false
+spring.h2.console.settings.web-allow-others=false
diff --git a/src/test/java/ru/ulstu/is/cbapp/CategoryServiceTests.java b/src/test/java/ru/ulstu/is/cbapp/CategoryServiceTests.java
new file mode 100644
index 0000000..253fc0e
--- /dev/null
+++ b/src/test/java/ru/ulstu/is/cbapp/CategoryServiceTests.java
@@ -0,0 +1,55 @@
+package ru.ulstu.is.cbapp;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.ulstu.is.cbapp.models.Student;
+import ru.ulstu.is.cbapp.models.Category;
+import ru.ulstu.is.cbapp.service.StudentService;
+import ru.ulstu.is.cbapp.service.CategoryService;
+
+@SpringBootTest
+public class CategoryServiceTests {
+    @Autowired
+    private CategoryService categoryService;
+
+    @Autowired
+    private StudentService studentService;
+
+
+    @Test
+    public void testAddStudent() {
+        studentService.deleteAllStudents();
+        categoryService.deleteAllCategories();
+
+        Category p = categoryService.addCategory("Category");
+        Student e = studentService.addStudent("1", "2", "33");
+
+        studentService.addCategory(e.getId(), p);
+        Assertions.assertTrue(studentService.findStudent(e.getId()).getCategories().contains(p));
+        Assertions.assertTrue(categoryService.findCategory(p.getId()).getStudents().contains(e));
+
+        studentService.deleteAllStudents();
+        categoryService.deleteAllCategories();
+
+    }
+
+    @Test
+    public void testDeleteStudent() {
+        studentService.deleteAllStudents();
+        categoryService.deleteAllCategories();
+
+        Category p = categoryService.addCategory("Category");
+        Student e = studentService.addStudent("1", "2", "33");
+
+        studentService.addCategory(e.getId(), p);
+        studentService.deleteCategory(e.getId(), p);
+        Assertions.assertFalse(studentService.findStudent(e.getId()).getCategories().contains(p));
+        Assertions.assertFalse(categoryService.findCategory(p.getId()).getStudents().contains(e));
+
+        studentService.deleteAllStudents();
+        categoryService.deleteAllCategories();
+
+    }
+}
diff --git a/src/test/java/ru/ulstu/is/cbapp/CbappApplicationTests.java b/src/test/java/ru/ulstu/is/cbapp/CbappApplicationTests.java
deleted file mode 100644
index 701a75a..0000000
--- a/src/test/java/ru/ulstu/is/cbapp/CbappApplicationTests.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package ru.ulstu.is.cbapp;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import ru.ulstu.is.cbapp.Lab2.service.ServiceCalculate;
-
-@SpringBootTest
-class CbappApplicationTests {
-
-	@Autowired
-	ServiceCalculate serviceCalculate;
-
-	@Test
-	void stringSum() {
-		Assertions.assertEquals("testData",serviceCalculate.add("test","Data","string"));
-		Assertions.assertEquals("1022",serviceCalculate.add("102","2","string"));
-	}
-	@Test
-	void numberSum() {
-		Assertions.assertEquals(104,serviceCalculate.add("102","2","number"));
-	}
-	@Test
-	void stringSut() {
-		Assertions.assertEquals("tt",serviceCalculate.sut("test","es","string"));
-		Assertions.assertEquals("10",serviceCalculate.sut("102","2","string"));
-	}
-	@Test
-	void numberSut() {
-		Assertions.assertEquals(100,serviceCalculate.sut(102,2,"number"));
-	}
-	@Test
-	void stringLen() {
-		Assertions.assertEquals("Длина = 4",serviceCalculate.len("test","string"));
-	}
-	@Test
-	void numberLen() {
-		Assertions.assertEquals(3,serviceCalculate.len(305,"number"));
-		Assertions.assertEquals(2,serviceCalculate.len(24,"number"));
-	}
-	@Test
-	void stringInv() {
-		Assertions.assertEquals("gnirts",serviceCalculate.inv("string","string"));
-	}
-	@Test
-	void numberInv() {
-		Assertions.assertEquals(-102,serviceCalculate.inv(102,"number"));
-		Assertions.assertEquals(12,serviceCalculate.inv(-12,"number"));
-	}
-
-}
diff --git a/src/test/java/ru/ulstu/is/cbapp/DrivingSchoolServiceTests.java b/src/test/java/ru/ulstu/is/cbapp/DrivingSchoolServiceTests.java
new file mode 100644
index 0000000..9cc2fda
--- /dev/null
+++ b/src/test/java/ru/ulstu/is/cbapp/DrivingSchoolServiceTests.java
@@ -0,0 +1,118 @@
+package ru.ulstu.is.cbapp;
+
+import javax.persistence.EntityNotFoundException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.ulstu.is.cbapp.models.DrivingSchool;
+import ru.ulstu.is.cbapp.models.Student;
+import ru.ulstu.is.cbapp.service.DrivingSchoolService;
+import ru.ulstu.is.cbapp.service.StudentService;
+
+@SpringBootTest
+public class DrivingSchoolServiceTests {
+    @Autowired
+    private DrivingSchoolService drivingSchoolService;
+
+    @Autowired
+    private StudentService studentService;
+
+
+    @Test
+    public void testDeleteAllDrivingSchools() {
+        drivingSchoolService.deleteAllDrivingSchools();
+        int n = 3;
+        for (int i = 0; i < n; i++) {
+            String name = "DrivingSchool" + i;
+            drivingSchoolService.addDrivingSchool(name);
+        }
+        drivingSchoolService.deleteAllDrivingSchools();
+        Assertions.assertEquals(drivingSchoolService.findAllDrivingSchools().size(), 0);
+    }
+
+    @Test
+    public void testDeleteDrivingSchool() {
+        drivingSchoolService.deleteAllDrivingSchools();
+        String name = "DrivingSchool1";
+        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
+        drivingSchoolService.deleteDrivingSchool(d.getId());
+        Assertions.assertThrows(EntityNotFoundException.class, () -> {
+            drivingSchoolService.findDrivingSchool(d.getId());});
+    }
+
+    @Test
+    public void testAddDrivingSchool() {
+        drivingSchoolService.deleteAllDrivingSchools();
+        String name = "DrivingSchool1";
+        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
+        Assertions.assertNotNull(drivingSchoolService.findDrivingSchool(d.getId()));
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+
+    @Test
+    public void testUpdateDrivingSchool() {
+        drivingSchoolService.deleteAllDrivingSchools();
+        String name = "DrivingSchool1";
+        drivingSchoolService.addDrivingSchool(name);
+        String name2 = "DrivingSchool2";
+        drivingSchoolService.updateDrivingSchool(drivingSchoolService.findDrivingSchool(name).getId(), name2);
+        Assertions.assertNotNull(drivingSchoolService.findDrivingSchool(name2));
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+
+
+    @Test
+    public void testFindAllDrivingSchools() {
+        drivingSchoolService.deleteAllDrivingSchools();
+        int n = 3;
+        for (int i = 0; i < n; i++) {
+            String name = "DrivingSchool" + i;
+            drivingSchoolService.addDrivingSchool(name);
+        }
+
+        Assertions.assertEquals(drivingSchoolService.findAllDrivingSchools().size(), n);
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+
+    @Test
+    public void testAddStudent() {
+
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+
+
+        final String name = "DrivingSchool";
+        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
+        Student newStudent = studentService.addStudent("cha", "chacha", "111");
+        drivingSchoolService.addNewStudent(d.getId(), newStudent);
+
+        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(newStudent));
+
+
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+
+    @Test
+    public void testDeleteStudent() {
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+
+
+        final String name = "DrivingSchool";
+        DrivingSchool d = drivingSchoolService.addDrivingSchool(name);
+        Student newStudent = studentService.addStudent("cha", "chacha", "111");
+
+        drivingSchoolService.addNewStudent(d.getId(), newStudent);
+        Assertions.assertTrue(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(newStudent));
+
+        drivingSchoolService.deleteStudent(d.getId(), newStudent);
+        DrivingSchool cFromDB =  drivingSchoolService.findDrivingSchool(d.getId());
+        Assertions.assertFalse(drivingSchoolService.findDrivingSchool(d.getId()).getStudents().contains(newStudent));
+
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+
+    }
+}
diff --git a/src/test/java/ru/ulstu/is/cbapp/StudentServiceTests.java b/src/test/java/ru/ulstu/is/cbapp/StudentServiceTests.java
new file mode 100644
index 0000000..a3968e2
--- /dev/null
+++ b/src/test/java/ru/ulstu/is/cbapp/StudentServiceTests.java
@@ -0,0 +1,92 @@
+package ru.ulstu.is.cbapp;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.ulstu.is.cbapp.models.DrivingSchool;
+import ru.ulstu.is.cbapp.models.Student;
+import ru.ulstu.is.cbapp.service.DrivingSchoolService;
+import ru.ulstu.is.cbapp.service.StudentService;
+
+@SpringBootTest
+public class StudentServiceTests {
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private DrivingSchoolService drivingSchoolService;
+
+    @Test
+    public void testAddStudent() {
+        studentService.deleteAllStudents();
+
+        studentService.addStudent("name", "surname", "111");
+        Assertions.assertEquals(1, studentService.findAllStudents().size());
+        studentService.deleteAllStudents();
+    }
+
+    @Test
+    public void testUpdateStudent() {
+        studentService.deleteAllStudents();
+        final String newName = "name";
+
+        Student e  = studentService.addStudent("surname", "name", "111");
+        studentService.updateDrivingSchool(e.getId(),e.getSurname(), newName, e.getPhoneNumber());
+        Assertions.assertEquals(newName, studentService.findStudent(e.getId()).getName());
+        studentService.deleteAllStudents();
+    }
+
+    @Test
+    public void testDeleteStudent() {
+        studentService.deleteAllStudents();
+
+        Student e = studentService.addStudent("name", "surname", "111");
+        studentService.deleteStudent(e.getId());
+        Assertions.assertEquals(0, studentService.findAllStudents().size());
+        studentService.deleteAllStudents();
+    }
+
+    @Test
+    public void testFindAllStudent() {
+        studentService.deleteAllStudents();
+        int n = 3;
+        for (int i = 0; i < n; i++) {
+            studentService.addStudent("name", "surname", "111");
+        }
+        Assertions.assertEquals(n, studentService.findAllStudents().size());
+        studentService.deleteAllStudents();
+    }
+
+    @Test
+    public void testAddDrivingSchool() {
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+
+        Student e = studentService.addStudent("name", "surname", "111");
+        DrivingSchool d = drivingSchoolService.addDrivingSchool("Comp");
+        drivingSchoolService.addNewStudent(d.getId(), e);
+        Assertions.assertEquals(d, studentService.findStudent(e.getId()).getDrivingSchool());
+
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+
+    @Test
+    public void testDeleteFromDrivingSchool() {
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+
+        Student e = studentService.addStudent("name", "surname", "111");
+        DrivingSchool d = drivingSchoolService.addDrivingSchool("Comp");
+
+        studentService.addDrivingSchool(e.getId(), d);
+        Assertions.assertEquals(d, studentService.findStudent(e.getId()).getDrivingSchool());
+
+        studentService.deleteDrivingSchool(e.getId());
+        Assertions.assertNull(studentService.findStudent(e.getId()).getDrivingSchool());
+
+        studentService.deleteAllStudents();
+        drivingSchoolService.deleteAllDrivingSchools();
+    }
+}