{"id":482575,"date":"2026-06-05T16:46:33","date_gmt":"2026-06-05T16:46:33","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=482575"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=482575","title":{"rendered":"Kawai-Focus 2.8: \u043f\u0443\u0442\u044c \u043a MVP1 \u2014 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/23c\/f67\/b1f\/23cf67b1fab2f3df52cff0cc32dd0cb8.png\" alt=\"\u041e\u0431\u043b\u043e\u0436\u043a\u0430\" title=\"\u041e\u0431\u043b\u043e\u0436\u043a\u0430\" width=\"780\" height=\"440\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/23c\/f67\/b1f\/23cf67b1fab2f3df52cff0cc32dd0cb8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/23c\/f67\/b1f\/23cf67b1fab2f3df52cff0cc32dd0cb8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041e\u0431\u043b\u043e\u0436\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<h3>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412\u0441\u0435\u043c \u0434\u043e\u0431\u0440\u043e\u0433\u043e \u0434\u043d\u044f! \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/napkincode.ru\/post\/kawai-focus\/kavaj-fokus-27-put-k-mvp1---tsepochka-tajmerov-i-vosproizvedenie-zvuka\/\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u0432\u0430\u0439-\u0424\u043e\u043a\u0443\u0441 2.7: \u043f\u0443\u0442\u044c \u043a MVP1 \u2014 \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0437\u0432\u0443\u043a\u0430<\/a>:<\/p>\n<ol>\n<li>\n<p><strong>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e<\/strong> \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0437\u0432\u0443\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 Web Audio API;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 <strong>\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f<\/strong> \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 \u0434\u043b\u044f <strong>Pomodoro<\/strong>.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u044f \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u044d\u043a\u0440\u0430\u043d <strong>\u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u00bb<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043e\u0431\u0440\u0430\u0437\u0446\u044b <strong>\u0441\u0435\u0441\u0441\u0438\u0439<\/strong>, \u043d\u0430\u0441\u0442\u0443\u043f\u0438\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0435\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u044b. \u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u044f \u043d\u0430\u043f\u0438\u0448\u0443 \u044d\u043a\u0440\u0430\u043d-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0442\u0430\u0439\u043c\u0435\u0440.<\/p>\n<p>\u0412\u0441\u0435 \u043d\u043e\u0432\u044b\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 <strong>SQLite3<\/strong>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <strong>CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e<\/strong> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430. <strong>\u0422\u0430\u043a\u0436\u0435<\/strong> \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044e <strong>\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/strong> \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <strong>\u0437\u0430\u043f\u0438\u0441\u0435\u0439<\/strong>. \u041a \u043d\u043e\u0432\u043e\u043c\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0443 \u043a\u043d\u043e\u043f\u043a\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u043c\u0438.<\/p>\n<p>\u0417\u0430\u0432\u0430\u0440\u0438\u0432\u0430\u0439\u0442\u0435 \u0447\u0430\u0439, \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043a\u0443\u0441\u043d\u044f\u0448\u043a\u0438 \u2014 \u043f\u043e\u0440\u0430 \u00ab\u0432\u044b\u0441\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u044f\u0434\u043a\u0438 \u0438\u0437 \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u043e\u0432\u00bb! \ud83c\udf45<\/p>\n<hr\/>\n<h3>Crud \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/h3>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u2014 \u043d\u0430\u043f\u0438\u0448\u0443 CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u0442\u0440\u043e\u043a\u0438 DML-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u043d\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e: \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u044b.<\/p>\n<h4>timerDML.ts<\/h4>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u044e \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043d\u043e\u0432\u044b\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414.<\/p>\n<pre><code class=\"typescript\">export const INSERT_TIMER = 'INSERT INTO timer (title, pomodoro_time, break_time, break_long_time, count_pomodoro) VALUES (?, ?, ?, ?, ?)'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>INSERT_TIMER<\/strong><\/code> \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>timer<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: <code>title<\/code>, <code>pomodoro_time<\/code>, <code>break_time<\/code>, <code>break_long_time<\/code>, <code>count_pomodoro<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u043b\u0435\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b <code>?<\/code> \u0434\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"typescript\">export const UPDATE_TIMER = 'UPDATE timer SET title = ?, pomodoro_time = ?, break_time = ?, break_long_time = ?, count_pomodoro = ? WHERE id = ?'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>UPDATE_TIMER<\/strong><\/code> \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430,<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e <code>id<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"typescript\">export const DELETE_TIMER = 'DELETE FROM timer WHERE id = ?'<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>DELETE_TIMER<\/strong><\/code> \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <code>timer<\/code> \u043f\u043e <code>id<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 \u0442\u0440\u0451\u0445, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. <\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435 \u044d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432 CRUD-\u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445.<\/p>\n<h4>timerCrud.ts<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0443 \u0441\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442 <code>timerDML.ts<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u0438 \u0442\u0430\u043a \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043e\u043d \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d.<\/p>\n<pre><code class=\"typescript\">\/** \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function createTimer(  title: string,   pomodoroTime: number,   breakTime: number,   breakLongTime: number,   countPomodoro: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(INSERT_TIMER, [    title,     pomodoroTime,     breakTime,     breakLongTime,     countPomodoro  ]);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>createTimer<\/strong><\/code> \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438\u0437 UI,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0411\u0414 \u0447\u0435\u0440\u0435\u0437 <code>getDb()<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>INSERT_TIMER<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>QueryResult<\/code> (\u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>lastInsertId<\/code>).<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"typescript\">\/** \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function updateTimer(  TimerId: number,  title: string,  pomodoroTime: number,  breakTime: number,  breakLongTime: number,  countPomodoro: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(UPDATE_TIMER, [    title,    pomodoroTime,    breakTime,    breakLongTime,    countPomodoro,    TimerId  ]);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>updateTimer<\/strong><\/code> \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>TimerId<\/code> \u0438 \u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f,<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>UPDATE_TIMER<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e <code>id<\/code>, \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043d\u043e\u0432\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"typescript\">\/** \u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function deleteTimer(  TimerId: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(DELETE_TIMER, [TimerId]);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code><strong>deleteTimer<\/strong><\/code> \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e <code>TimerId<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>DELETE_TIMER<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u0431\u0430\u0437\u044b.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e\u0432\u044b\u0435 CRUD-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0433\u043e\u0442\u043e\u0432\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e view \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<hr\/>\n<h3>TimerUpdate<\/h3>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d view <code>TimerUpdate<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u043e\u043b\u044c \u0444\u043e\u0440\u043c\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043e\u0434\u0438\u043d view \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0438 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u0434\u0430 \u0438 \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0432\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<p>\u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0443\u0442\u0438\u043d\u043d\u044b\u0435 \u0432\u0435\u0449\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u0442\u0438\u043b\u0438 CSS \u0438\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u043e\u0443\u0442\u043e\u0432, \u0438 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0443\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0435\u0433\u043e HTML.<\/p>\n<h4>TimerUpdate.ts<\/h4>\n<p>\u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 view, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b \u0438 \u0442.\u0434.<\/p>\n<pre><code class=\"typescript\">import { computed, defineComponent, onMounted, ref, watch } from 'vue';import { IonIcon, IonPage, IonContent } from '@ionic\/vue';import { useRoute, useRouter } from 'vue-router';import { arrowBackOutline, checkmarkOutline } from 'ionicons\/icons';import { createTimer, getTimer, updateTimer } from '@\/db\/crud\/timerCrud';import type { TimerRow } from '@\/types\/timerType';const LIMITS = {  pomodoroTime: { min: 10, max: 90 },  breakTime: { min: 3, max: 10 },  breakLongTime: { min: 15, max: 40 },  countPomodoro: { min: 2, max: 8 },} as const;export default defineComponent({  name: 'TimerUpdate',  components: { IonIcon, IonPage, IonContent },  setup() {    const route = useRoute();    const router = useRouter();    const isCreateMode = computed(() =&gt; route.params.id = 'new');    const currentId = computed(() =&gt; (isCreateMode.value ? 0 : Number(route.params.id)));    const loading = ref(false);    const error = ref&lt;string | null&gt;(null);    const titleError = ref('');    const modeLabel = computed(() =&gt; (isCreateMode.value ? '\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440' : '\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440'));    const form = ref&lt;TimerRow&gt;({      id: currentId.value,      title: '',      pomodoro_time: LIMITS.pomodoroTime.min,      break_time: LIMITS.breakTime.min,      break_long_time: LIMITS.breakLongTime.min,      count_pomodoro: LIMITS.countPomodoro.min,    });    \/**     * \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0447\u0438\u0441\u043b\u043e.     * \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.     *\/    const safeNumber = (value: unknown, fallback: number): number =&gt; {      const parsed = Number(value);      return Number.isFinite(parsed) ? parsed : fallback;    };    \/**     * \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c min-max.     *\/    const clamp = (value: number, min: number, max: number): number =&gt; {      return Math.min(max, Math.max(min, value));    };    \/**     * \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f     * \u043a \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.     *\/    const normalizeTimer = (timer?: Partial&lt;TimerRow&gt;): TimerRow =&gt; {      return {        id: currentId.value,        title: timer?.title ?? '',        pomodoro_time: clamp(safeNumber(timer?.pomodoro_time, LIMITS.pomodoroTime.min), LIMITS.pomodoroTime.min, LIMITS.pomodoroTime.max),        break_time: clamp(safeNumber(timer?.break_time, LIMITS.breakTime.min), LIMITS.breakTime.min, LIMITS.breakTime.max),        break_long_time: clamp(safeNumber(timer?.break_long_time, LIMITS.breakLongTime.min), LIMITS.breakLongTime.min, LIMITS.breakLongTime.max),        count_pomodoro: clamp(safeNumber(timer?.count_pomodoro, LIMITS.countPomodoro.min), LIMITS.countPomodoro.min, LIMITS.countPomodoro.max),      };    };    \/**     * \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u0444\u043e\u0440\u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c.     *\/    const clampField = (field: keyof TimerRow, min: number, max: number): void =&gt; {      if (typeof form.value[field] = 'number') {        form.value[field] = clamp(safeNumber(form.value[field], min), min, max) as never;      }    };    \/**     * \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u0430.     *\/    const onSliderInput = (field: keyof TimerRow, min: number, max: number, value: Event): void =&gt; {      const nextValue = safeNumber((value.target as HTMLInputElement | null)?.value, min);      if (typeof form.value[field] = 'number') {        form.value[field] = clamp(nextValue, min, max) as never;      }    };    \/**     * \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0431\u043e     * \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0444\u043e\u0440\u043c\u0443 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.     *\/    const loadTimer = async (): Promise&lt;void&gt; =&gt; {      if (isCreateMode.value) {        form.value = normalizeTimer({          id: 0,          title: '',          pomodoro_time: LIMITS.pomodoroTime.min,          break_time: LIMITS.breakTime.min,          break_long_time: LIMITS.breakLongTime.min,          count_pomodoro: LIMITS.countPomodoro.min,        });        return;      }      loading.value = true;      error.value = null;      try {        const timer = await getTimer(currentId.value);        form.value = normalizeTimer(timer);      } catch (e) {        error.value = e instanceof Error ? e.message : '\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430';      } finally {        loading.value = false;      }    };    \/**     * \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.     *\/    const validateTitle = (): boolean =&gt; {      const trimmedTitle = form.value.title.trim();      if (!trimmedTitle) {        titleError.value = '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430';        return false;      }      titleError.value = '';      return true;    };    \/**     * \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439.     *\/    const saveTimer = async (): Promise&lt;void&gt; =&gt; {      if (!validateTitle()) {        return;      }      try {        const trimmedTitle = form.value.title.trim();        form.value = normalizeTimer({          id: isCreateMode.value ? 0 : currentId.value,          title: trimmedTitle,          pomodoro_time: form.value.pomodoro_time,          break_time: form.value.break_time,          break_long_time: form.value.break_long_time,          count_pomodoro: form.value.count_pomodoro,        });        if (isCreateMode.value) {          const result = await createTimer(            form.value.title,            form.value.pomodoro_time,            form.value.break_time,            form.value.break_long_time,            form.value.count_pomodoro,          );          const newId = Number((result as { lastInsertId?: number }).lastInsertId ?? 0);          if (!newId) {            throw new Error('\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c id \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430');          }          router.push(`\/timer\/${newId}`);          return;        }        await updateTimer(          currentId.value,          form.value.title,          form.value.pomodoro_time,          form.value.break_time,          form.value.break_long_time,          form.value.count_pomodoro,        );        router.push(`\/timer\/${currentId.value}`);      } catch (e) {        error.value = e instanceof Error ? e.message : '\u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430';      }    };    \/**     * \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443.     *\/    const goBack = (): void =&gt; {      router.back();    };    onMounted(loadTimer);    watch(() =&gt; route.params.id, () =&gt; {      loadTimer();    });    watch(() =&gt; form.value.title, () =&gt; {      if (titleError.value &amp;&amp; form.value.title.trim()) {        titleError.value = '';      }    });    return {      form,      loading,      error,      titleError,      isCreateMode,      modeLabel,      LIMITS,      arrowBackOutline,      checkmarkOutline,      clampField,      onSliderInput,      saveTimer,      validateTitle,      goBack,    };  },});<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<ol>\n<li>\n<p><strong>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0436\u0438\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b<\/strong> \u2014 \u0447\u0435\u0440\u0435\u0437 <code>isCreateMode<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u044b \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 (\u043f\u043e <a href=\"http:\/\/route.params.id\" rel=\"noopener noreferrer nofollow\"><code>route.params.id<\/code><\/a>).<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u043e\u0440\u043c\u044b<\/strong> \u2014 <code>form<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0437 <code>LIMITS<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0430\u0449\u0438\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong> \u2014 <code>safeNumber<\/code> \u0438 <code>clamp<\/code> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442:<\/p>\n<ul>\n<li>\n<p>\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong> \u2014 <code>normalizeTimer<\/code> \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0431\u0430\u0437\u044b \u043a \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443 \u0438 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e UI \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong> \u2014 <code>loadTimer<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0451\u0442 \u0434\u0435\u0444\u043e\u043b\u0442\u044b,<\/p>\n<\/li>\n<li>\n<p>\u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u0437 \u0411\u0414 \u0447\u0435\u0440\u0435\u0437 <code>getTimer<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0444\u043e\u0440\u043c\u044b<\/strong> \u2014 <code>validateTitle<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0435, \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<\/li>\n<li>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u044b<\/strong> \u2014 <code>onSliderInput<\/code> \u0438 <code>clampField<\/code> \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0443\u044e\u0442 UI \u0438 \u0444\u043e\u0440\u043c\u0443, \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0432\u044b\u0439\u0442\u0438 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b <code>LIMITS<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong> \u2014 <code>saveTimer<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u0443\u0435\u0442 \u0444\u043e\u0440\u043c\u0443,<\/p>\n<\/li>\n<li>\n<p>\u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435,<\/p>\n<\/li>\n<li>\n<p>\u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 (<code>createTimer<\/code>),<\/p>\n<\/li>\n<li>\n<p>\u043b\u0438\u0431\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 (<code>updateTimer<\/code>),<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043d\u0430\u0437\u0430\u0434<\/strong> \u2014 <code>goBack<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u044d\u043a\u0440\u0430\u043d \u0447\u0435\u0440\u0435\u0437 <code>router.back()<\/code>.<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f<\/strong>:<\/p>\n<ul>\n<li>\n<p><code>watch(<\/code><a href=\"http:\/\/route.params.id\" rel=\"noopener noreferrer nofollow\"><code>route.params.id<\/code><\/a><code>)<\/code> \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 \u043f\u0440\u0438 \u0441\u043c\u0435\u043d\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430,<\/p>\n<\/li>\n<li>\n<p><code>watch(form.title)<\/code> \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0447\u0430\u043b \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u0435.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430<\/strong> \u2014 <code>onMounted(loadTimer)<\/code> \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<\/li>\n<\/ol>\n<h4>TimerUpdate.html<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0443 HTML \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e view, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<pre><code class=\"xml\">&lt;ion-page&gt;  &lt;ion-content&gt;    &lt;div class=\"timer-update-container\"&gt;      &lt;div class=\"page-header\"&gt;        &lt;button class=\"back-button\" type=\"button\" @click=\"goBack\"&gt;          &lt;ion-icon :icon=\"arrowBackOutline\"&gt;&lt;\/ion-icon&gt;          \u041d\u0430\u0437\u0430\u0434        &lt;\/button&gt;        &lt;h1&gt;{{ modeLabel }}&lt;\/h1&gt;        &lt;p&gt;\u041f\u043e\u0434\u0441\u0442\u0440\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u044b.&lt;\/p&gt;      &lt;\/div&gt;      &lt;div class=\"form-shell\"&gt;        &lt;div v-if=\"loading\" class=\"state-card\"&gt;\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430...&lt;\/div&gt;        &lt;div v-else-if=\"error\" class=\"state-card error\"&gt;{{ error }}&lt;\/div&gt;        &lt;form v-else class=\"timer-form\" @submit.prevent=\"saveTimer\"&gt;          &lt;label class=\"field-card\"&gt;            &lt;span class=\"field-label\"&gt;\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435&lt;\/span&gt;            &lt;input              class=\"title-input\"              :class=\"{ 'title-input--error': titleError }\"              v-model=\"form.title\"              type=\"text\"              maxlength=\"100\"              placeholder=\"\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0423\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u043e\u043a\u0443\u0441\"            \/&gt;            &lt;p v-if=\"titleError\" class=\"field-error\"&gt;{{ titleError }}&lt;\/p&gt;          &lt;\/label&gt;          &lt;section class=\"field-card tomato-card\"&gt;            &lt;div class=\"field-head\"&gt;              &lt;span class=\"field-label\"&gt;\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u043e\u0432&lt;\/span&gt;            &lt;\/div&gt;            &lt;div class=\"tomato-stage\"&gt;              &lt;div class=\"tomato-display\"&gt;                &lt;span class=\"tomato-emoji\"&gt;\ud83c\udf45&lt;\/span&gt;                &lt;strong&gt;{{ form.count_pomodoro }}&lt;\/strong&gt;              &lt;\/div&gt;              &lt;input                v-model.number=\"form.count_pomodoro\"                type=\"range\"                :min=\"LIMITS.countPomodoro.min\"                :max=\"LIMITS.countPomodoro.max\"                @input=\"onSliderInput('count_pomodoro', LIMITS.countPomodoro.min, LIMITS.countPomodoro.max, $event)\"              \/&gt;            &lt;\/div&gt;          &lt;\/section&gt;          &lt;section class=\"field-card slider-card\"&gt;            &lt;div class=\"field-head\"&gt;              &lt;span class=\"field-label\"&gt;\u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u0430&lt;\/span&gt;            &lt;\/div&gt;            &lt;div class=\"slider-wrap\"&gt;              &lt;div class=\"value-pill\"&gt;                {{ form.pomodoro_time }}&lt;small&gt;\u043c\u0438\u043d&lt;\/small&gt;              &lt;\/div&gt;              &lt;input                v-model.number=\"form.pomodoro_time\"                type=\"range\"                :min=\"LIMITS.pomodoroTime.min\"                :max=\"LIMITS.pomodoroTime.max\"                @input=\"onSliderInput('pomodoro_time', LIMITS.pomodoroTime.min, LIMITS.pomodoroTime.max, $event)\"              \/&gt;            &lt;\/div&gt;            &lt;p class=\"range-note\"&gt;              \u041f\u0440\u0435\u0434\u0435\u043b\u044b: {{ LIMITS.pomodoroTime.min }} \u2014 {{ LIMITS.pomodoroTime.max }} \u043c\u0438\u043d\u0443\u0442            &lt;\/p&gt;          &lt;\/section&gt;          &lt;section class=\"field-card slider-card\"&gt;            &lt;div class=\"field-head\"&gt;              &lt;span class=\"field-label\"&gt;\u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0440\u044b\u0432&lt;\/span&gt;            &lt;\/div&gt;            &lt;div class=\"slider-wrap\"&gt;              &lt;div class=\"value-pill\"&gt;                {{ form.break_time }}&lt;small&gt;\u043c\u0438\u043d&lt;\/small&gt;              &lt;\/div&gt;              &lt;input                v-model.number=\"form.break_time\"                type=\"range\"                :min=\"LIMITS.breakTime.min\"                :max=\"LIMITS.breakTime.max\"                @input=\"onSliderInput('break_time', LIMITS.breakTime.min, LIMITS.breakTime.max, $event)\"              \/&gt;            &lt;\/div&gt;            &lt;p class=\"range-note\"&gt;              \u041f\u0440\u0435\u0434\u0435\u043b\u044b: {{ LIMITS.breakTime.min }} \u2014 {{ LIMITS.breakTime.max }} \u043c\u0438\u043d\u0443\u0442            &lt;\/p&gt;          &lt;\/section&gt;          &lt;section class=\"field-card slider-card\"&gt;            &lt;div class=\"field-head\"&gt;              &lt;span class=\"field-label\"&gt;\u0414\u043b\u0438\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0440\u044b\u0432&lt;\/span&gt;            &lt;\/div&gt;            &lt;div class=\"slider-wrap\"&gt;              &lt;div class=\"value-pill\"&gt;                {{ form.break_long_time }}&lt;small&gt;\u043c\u0438\u043d&lt;\/small&gt;              &lt;\/div&gt;              &lt;input                v-model.number=\"form.break_long_time\"                type=\"range\"                :min=\"LIMITS.breakLongTime.min\"                :max=\"LIMITS.breakLongTime.max\"                @input=\"onSliderInput('break_long_time', LIMITS.breakLongTime.min, LIMITS.breakLongTime.max, $event)\"              \/&gt;            &lt;\/div&gt;            &lt;p class=\"range-note\"&gt;              \u041f\u0440\u0435\u0434\u0435\u043b\u044b: {{ LIMITS.breakLongTime.min }} \u2014 {{ LIMITS.breakLongTime.max }} \u043c\u0438\u043d\u0443\u0442            &lt;\/p&gt;          &lt;\/section&gt;          &lt;button class=\"save-button\" type=\"submit\"&gt;            &lt;ion-icon :icon=\"checkmarkOutline\"&gt;&lt;\/ion-icon&gt;            \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c          &lt;\/button&gt;        &lt;\/form&gt;      &lt;\/div&gt;    &lt;\/div&gt;  &lt;\/ion-content&gt;&lt;\/ion-page&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<ol>\n<li>\n<p><strong>\u041a\u0430\u0440\u043a\u0430\u0441 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/strong> \u2014 <code>&lt;ion-page&gt;<\/code> \u0438 <code>&lt;ion-content&gt;<\/code> \u0437\u0430\u0434\u0430\u044e\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0430 Ionic-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u0432\u0435\u0441\u044c UI \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u0428\u0430\u043f\u043a\u0430 \u044d\u043a\u0440\u0430\u043d\u0430<\/strong> \u2014 \u0431\u043b\u043e\u043a <code>page-header<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>\u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u041d\u0430\u0437\u0430\u0434\u00bb<\/strong>, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0443\u044e <code>goBack<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0440\u0435\u0436\u0438\u043c\u0430 (<code>modeLabel<\/code>),<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/strong> \u2014 \u0447\u0435\u0440\u0435\u0437 <code>v-if \/ v-else-if \/ v-else<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043b\u043e\u0433\u0438\u043a\u0430:<\/p>\n<ul>\n<li>\n<p><code>loading<\/code> \u2192 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430,<\/p>\n<\/li>\n<li>\n<p><code>error<\/code> \u2192 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430,<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0430\u0447\u0435 \u2192 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0444\u043e\u0440\u043c\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong> \u2014 \u0434\u0432\u0443\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 <code>v-model=\"form.title\"<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0445\u0440\u0430\u043d\u0438\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 <code>titleError<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e <code>maxlength = 100<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f<\/strong> \u2014 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0434 \u043f\u043e\u043b\u0435\u043c, \u0430 CSS-\u043a\u043b\u0430\u0441\u0441 <code>title-input--error<\/code> \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0432\u0432\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043b\u0430\u0439\u0434\u0435\u0440 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u043e\u0432<\/strong> \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>form.count_pomodoro<\/code>:<\/p>\n<ul>\n<li>\n<p>\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u044f\u0434\u043e\u043c \u0441 \ud83c\udf45,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c \u0438\u0437 <code>LIMITS<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u0434\u0443\u0442 \u0447\u0435\u0440\u0435\u0437 <code>onSliderInput<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0421\u043b\u0430\u0439\u0434\u0435\u0440 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u0430<\/strong> \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>pomodoro_time<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0432 <code>value-pill<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0438\u0436\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0421\u043b\u0430\u0439\u0434\u0435\u0440 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0440\u044b\u0432\u0430<\/strong> \u2014 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f <code>break_time<\/code>:<\/p>\n<ul>\n<li>\n<p>\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0444\u043e\u0440\u043c\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 <code>v-model.number<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 \u0447\u0435\u0440\u0435\u0437 <code>LIMITS<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0421\u043b\u0430\u0439\u0434\u0435\u0440 \u0434\u043b\u0438\u043d\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0440\u044b\u0432\u0430<\/strong> \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 <code>break_long_time<\/code>:<\/p>\n<ul>\n<li>\n<p>\u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u043e\u0432<\/strong> \u2014 \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043f\u043e \u0435\u0434\u0438\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<ul>\n<li>\n<p>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2192 <code>v-model<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u2192 <code>LIMITS<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u2192 <code>onSliderInput<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/strong> \u2014 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442 <code>saveTimer<\/code>:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 submit,<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430,<\/p>\n<\/li>\n<li>\n<p>\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>UX-\u0444\u043e\u043a\u0443\u0441 \u044d\u043a\u0440\u0430\u043d\u0430<\/strong> \u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c:<\/p>\n<ul>\n<li>\n<p>\u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0435\u043b \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435,<\/p>\n<\/li>\n<li>\n<p>\u043c\u043e\u0433 \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u044b \u0431\u0435\u0437 \u0440\u0443\u0447\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430,<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u043b \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u042f \u0440\u0430\u0434, \u0447\u0442\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0441 \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0443 \u043a \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044e \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044e \u043d\u043e\u0432\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 views.<\/p>\n<hr\/>\n<h3>Timer<\/h3>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c view \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430. \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u044f \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 \u0442\u0430\u0439\u043c\u0435\u0440 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u041d\u0430\u0437\u0430\u0434\u00bb. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u043d\u0430\u0447\u0435, \u043a\u0440\u043e\u043c\u0435 \u043a\u0430\u043a \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u043e\u043a\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u0436\u0430\u0432 \u043d\u0430 \u043a\u0440\u0435\u0441\u0442\u0438\u043a.<\/p>\n<h4>Timer.ts<\/h4>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u043e\u0432\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u041d\u0430\u0437\u0430\u0434\u00bb \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0435\u0451 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u042f \u043d\u0435 \u0445\u043e\u0447\u0443 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0451 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044f \u0445\u043e\u0447\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0442\u043e\u0447\u043d\u044f\u0442\u044c \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u043e\u043d \u0445\u043e\u0447\u0435\u0442 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 \u0438 \u0432\u044b\u0439\u0442\u0438. \u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u043f\u0430\u0443\u0437\u0435. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0430\u043b \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0421\u0442\u043e\u043f\u00bb, \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0435\u0433\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u00ab\u041d\u0430\u0437\u0430\u0434\u00bb.<\/p>\n<pre><code class=\"typescript\">\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434\/** \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \"\u041d\u0430\u0437\u0430\u0434\". *\/const showBackButton = computed(() =&gt; {  return (    state.value = 'paused' ||    (state.value = 'idle' &amp;&amp;      countdown.value?.isRunning.value = false &amp;&amp;      countdown.value?.timerNow.value ! undefined)  );});\/** \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430. *\/const askLeaveTimer = (): void =&gt; {  if (state.value = 'paused') {    confirmLeave.value = true;    return;  }  router.back();};\/** \u0417\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0430. *\/const closeLeaveModal = (): void =&gt; {  confirmLeave.value = false;};\/** \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430. *\/const confirmLeaveTimer = (): void =&gt; {  confirmLeave.value = false;  countdown.value?.stop();  state.value = 'idle';  router.back();};\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<p><strong>1. \u041b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 &#171;\u041d\u0430\u0437\u0430\u0434&#187;<\/strong>  <br \/> <code>showBackButton<\/code> \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442, \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u0432\u044b\u0445\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u043d\u0430 \u043f\u0430\u0443\u0437\u0435 \u2192 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c,<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0432 <code>idle<\/code>, \u043d\u043e \u0443\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0441\u044f \u0440\u0430\u043d\u044c\u0448\u0435 \u2192 \u0442\u043e\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c,<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0430\u0447\u0435 \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u043a\u0440\u044b\u0442\u0430. <strong>2. \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong>   <code>askLeaveTimer<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043b\u0438\u043a \u043f\u043e &#171;\u041d\u0430\u0437\u0430\u0434&#187;:<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u043f\u0430\u0443\u0437\u0435 \u2192 \u043d\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0441\u0440\u0430\u0437\u0443,<\/p>\n<ul>\n<li>\n<p>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f,<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u0435\u043d \u2192 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0437\u0430\u0434. <strong>3. \u0417\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430<\/strong>   <code>closeLeaveModal<\/code>:<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0444\u043b\u0430\u0433 <code>confirmLeave<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435. <strong>4. \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u044b\u0445\u043e\u0434\u0430<\/strong>   <code>confirmLeaveTimer<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0432\u044b\u0445\u043e\u0434:<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e,<\/p>\n<\/li>\n<li>\n<p>\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 (<code>stop()<\/code>),<\/p>\n<\/li>\n<li>\n<p>\u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 <code>idle<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u044d\u043a\u0440\u0430\u043d.<\/p>\n<\/li>\n<\/ul>\n<h4>Timer.html<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044f \u043d\u0430\u043f\u0438\u0448\u0443 <code>.html<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435.<\/p>\n<pre><code class=\"xml\">&lt;div class=\"page-header\"&gt;  &lt;button    v-if=\"showBackButton\"    class=\"btn-back\"    type=\"button\"    @click=\"askLeaveTimer\"  &gt;    &lt;ion-icon :icon=\"arrowBackOutline\"&gt;&lt;\/ion-icon&gt;    \u041d\u0430\u0437\u0430\u0434  &lt;\/button&gt;  &lt;h1&gt;\u0422\u0430\u0439\u043c\u0435\u0440&lt;\/h1&gt;&lt;\/div&gt;&lt;div  v-if=\"confirmLeave\"  class=\"confirm-overlay\"  @click.self=\"closeLeaveModal\"&gt;  &lt;div class=\"confirm-card\"&gt;    &lt;h3&gt;\u0412\u044b\u0439\u0442\u0438 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430?&lt;\/h3&gt;    &lt;p&gt;      \u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u0431\u0440\u043e\u0448\u0435\u043d, \u0435\u0441\u043b\u0438 \u0432\u044b \u0443\u0439\u0434\u0451\u0442\u0435 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430.    &lt;\/p&gt;    &lt;div class=\"confirm-actions\"&gt;      &lt;button        class=\"btn-timer btn-timer-pause\"        type=\"button\"        @click=\"closeLeaveModal\"      &gt;        \u041d\u0435\u0442      &lt;\/button&gt;      &lt;button        class=\"btn-timer btn-timer-stop\"        type=\"button\"        @click=\"confirmLeaveTimer\"      &gt;        \u0414\u0430      &lt;\/button&gt;    &lt;\/div&gt;  &lt;\/div&gt;&lt;\/div&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<p><strong>1. \u0428\u0430\u043f\u043a\u0430 \u044d\u043a\u0440\u0430\u043d\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong>  <br \/> \u0411\u043b\u043e\u043a <code>page-header<\/code> \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0432\u0435\u0440\u0445\u043d\u044e\u044e \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:<\/p>\n<ul>\n<li>\n<p>\u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u041d\u0430\u0437\u0430\u0434\u00bb (\u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u043b\u043e\u0433\u0438\u043a\u043e\u0439 <code>showBackButton<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u00bb <strong>2. \u0423\u0441\u043b\u043e\u0432\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430<\/strong>   \u041a\u043d\u043e\u043f\u043a\u0430 \u043d\u0430\u0437\u0430\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>v-if=\"showBackButton\"<\/code>:<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u0445 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>askLeaveTimer<\/code>, \u0430 \u043d\u0435 \u043f\u0440\u044f\u043c\u043e\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434<\/p>\n<\/li>\n<li>\n<p>\u044d\u0442\u043e \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 \u043f\u043e\u0442\u0435\u0440\u0438 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430 <strong>3. \u041c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0430<\/strong>   \u041a\u043d\u043e\u043f\u043a\u0430 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 <code>router.back()<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e:<\/p>\n<\/li>\n<li>\n<p>\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 <strong>4. \u041e\u0432\u0435\u0440\u043b\u0435\u0439 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0430<\/strong>   <code>confirm-overlay<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 <code>v-if=\"confirmLeave\"<\/code>:<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0435\u0442 \u0444\u043e\u043d \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u0432\u043d\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 (<code>@click.self<\/code>) <strong>5. \u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/strong>   <code>confirm-card<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0441 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c \u00ab\u0412\u044b\u0439\u0442\u0438 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430?\u00bb<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0441\u0431\u0440\u043e\u0448\u0435\u043d<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441 \u0434\u0432\u0443\u043c\u044f \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 <strong>6. \u041a\u043d\u043e\u043f\u043a\u0430 &#171;\u041d\u0435\u0442&#187;<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>closeLeaveModal<\/code><\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 <strong>7. \u041a\u043d\u043e\u043f\u043a\u0430 &#171;\u0414\u0430&#187;<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>confirmLeaveTimer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u0432\u044b\u0445\u043e\u0434:<\/p>\n<ul>\n<li>\n<p>\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u044d\u043a\u0440\u0430\u043d <strong>8. UX-\u043b\u043e\u0433\u0438\u043a\u0430 \u0437\u0430\u0449\u0438\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430<\/strong>   \u0412\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430:<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043f\u0440\u044f\u043c\u043e\u0439 \u0432\u044b\u0445\u043e\u0434 \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d \u0432 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u0445<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434 \u0441\u0431\u0440\u043e\u0441\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442 \u201c\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e\u201d \u0438 \u201c\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u201d<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c.<\/p>\n<hr\/>\n<h3>TimersList<\/h3>\n<p>\u041e\u0441\u0442\u0430\u043b\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 view, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430. \u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u043a \u043b\u043e\u0433\u0438\u043a\u0435: \u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u00bb \u0438 \u00ab\u0423\u0434\u0430\u043b\u0438\u0442\u044c\u00bb. \u0422\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0443 \u043d\u0430\u0434 \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432.<\/p>\n<h4>TimersList.ts<\/h4>\n<p>\u0412 \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 views. \u0422\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u0430 \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 \u043f\u043e\u0441\u043b\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.<\/p>\n<pre><code class=\"typescript\">\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434\/** ID \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f *\/const confirmDeleteId = ref&lt;number | null&gt;(null)const router = useRouter()const route = useRoute()\/** \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430 *\/const goToTimer = (id: number) =&gt; {  router.push(`\/timer\/${id}`)}\/** \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430 *\/const goToCreateTimer = () =&gt; {  router.push('\/timer-update\/new')}\/** \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 *\/const goToEditTimer = (id: number) =&gt; {  router.push(`\/timer-update\/${id}`)}\/** \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 *\/const askDeleteTimer = (id: number): void =&gt; {  confirmDeleteId.value = id}\/** \u041e\u0442\u043c\u0435\u043d\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 *\/const cancelDeleteTimer = (): void =&gt; {  confirmDeleteId.value = null}\/** \u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a *\/const removeTimer = async (): Promise&lt;void&gt; =&gt; {  if (confirmDeleteId.value = null) {    return  }  try {    await deleteTimer(confirmDeleteId.value)    confirmDeleteId.value = null    await loadTimers()  } catch (e: unknown) {    error.value = e instanceof Error ? e.message : '\u041e\u0448\u0438\u0431\u043a\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430'  }}\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434\/** \u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \/timers *\/watch(  () =&gt; route.fullPath,  (path) =&gt; {    if (path = '\/timers') {      loadTimers()    }  },  { immediate: false })\/\/ \u0414\u0440\u0443\u0433\u043e\u0439 \u043a\u043e\u0434<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<p><strong>1. <\/strong><code><strong>confirmDeleteId<\/strong><\/code><strong> \u2014 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 ID \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong>  <br \/> <code>confirmDeleteId<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0431\u0440\u0430\u043b \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p><code>null<\/code> \u2192 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0447\u0438\u0441\u043b\u043e \u2192 \u043e\u0442\u043a\u0440\u044b\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f <strong>2. <\/strong><code><strong>router<\/strong><\/code><strong> \u0438 <\/strong><code><strong>route<\/strong><\/code><strong> \u2014 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430<\/strong><\/p>\n<\/li>\n<li>\n<p><code>router<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p><code>route<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c URL \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 <strong>3. <\/strong><code><strong>goToTimer<\/strong><\/code><strong> \u2014 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u0442\u0430\u0439\u043c\u0435\u0440\u0443<\/strong>   \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>id<\/code><\/p>\n<\/li>\n<li>\n<p>\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 <code>\/timer\/{id}<\/code><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 <code>router.push<\/code> <strong>4. <\/strong><code><strong>goToCreateTimer<\/strong><\/code><strong> \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong>   \u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>\u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 <code>\/timer-update\/new<\/code><\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0435\u0434\u0438\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0444\u043e\u0440\u043c\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <strong>5. <\/strong><code><strong>goToEditTimer<\/strong><\/code><strong> \u2014 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong>   \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>id<\/code><\/p>\n<\/li>\n<li>\n<p>\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 <code>\/timer-update\/{id}<\/code><\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 <strong>6. <\/strong><code><strong>askDeleteTimer<\/strong><\/code><strong> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong>   \u0418\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 <code>id<\/code> \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0432 <code>confirmDeleteId<\/code><\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f <strong>7. <\/strong><code><strong>cancelDeleteTimer<\/strong><\/code><strong> \u2014 \u043e\u0442\u043c\u0435\u043d\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong>   \u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f:<\/p>\n<\/li>\n<li>\n<p>\u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 <code>confirmDeleteId = null<\/code><\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043e\u043a\u043d\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 <strong>8. <\/strong><code><strong>removeTimer<\/strong><\/code><strong> \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong>   \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u0431\u0430\u0437\u044b:<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e <code>confirmDeleteId<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>deleteTimer<\/code> (CRUD \u0441\u043b\u043e\u0439)<\/p>\n<\/li>\n<li>\n<p>\u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0435\u0440\u0435\u0437 <code>loadTimers<\/code><\/p>\n<\/li>\n<li>\n<p>\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 <code>error<\/code> <strong>9. <\/strong><code><strong>watch(route.fullPath)<\/strong><\/code><strong> \u2014 \u0440\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e<\/strong>   \u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043c\u0435\u043d\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430:<\/p>\n<\/li>\n<li>\n<p>\u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 <code>\/timers<\/code><\/p>\n<\/li>\n<li>\n<p>\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0435\u0437 \u0440\u0443\u0447\u043d\u043e\u0433\u043e refresh<\/p>\n<\/li>\n<\/ul>\n<h4>TimersList.html<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432 HTML.<\/p>\n<pre><code class=\"xml\">&lt;div  v-if=\"confirmDeleteId ! null\"  class=\"confirm-overlay\"  @click.self=\"cancelDeleteTimer\"&gt;  &lt;div class=\"confirm-card\"&gt;    &lt;h3&gt;\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440?&lt;\/h3&gt;    &lt;p&gt;\u042d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c.&lt;\/p&gt;    &lt;div class=\"confirm-actions\"&gt;      &lt;button        class=\"btn btn-secondary\"        type=\"button\"        @click=\"cancelDeleteTimer\"      &gt;        \u041e\u0442\u043c\u0435\u043d\u0430      &lt;\/button&gt;      &lt;button        class=\"btn btn-danger\"        type=\"button\"        @click=\"removeTimer\"      &gt;        \u0423\u0434\u0430\u043b\u0438\u0442\u044c      &lt;\/button&gt;    &lt;\/div&gt;  &lt;\/div&gt;&lt;\/div&gt;&lt;button  @click=\"goToCreateTimer\"  class=\"add-timer-button\"  type=\"button\"&gt;  &lt;ion-icon :icon=\"addCircleOutline\"&gt;&lt;\/ion-icon&gt;  \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440&lt;\/button&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u043e \u0448\u0430\u0433\u0430\u043c:<\/strong><\/p>\n<p><strong>1. \u041e\u0432\u0435\u0440\u043b\u0435\u0439 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong>  <br \/> \u0411\u043b\u043e\u043a <code>confirm-overlay<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438:<\/p>\n<ul>\n<li>\n<p><code>confirmDeleteId ! null<\/code><\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043b \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 <strong>2. \u041c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/strong>   <code>confirm-card<\/code> \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442:<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u043f\u0440\u043e\u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f <strong>\u00ab\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440?\u00bb<\/strong><\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u043d\u0435\u043e\u0431\u0440\u0430\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043a\u043d\u043e\u043f\u043a\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f <strong>3. \u0417\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u0432\u043d\u0435 \u043e\u043a\u043d\u0430<\/strong>   <code>@click.self=\"cancelDeleteTimer\"<\/code>:<\/p>\n<\/li>\n<li>\n<p>\u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043d\u0430 \u0444\u043e\u043d<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0431\u0435\u0437 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f <strong>4. \u041a\u043d\u043e\u043f\u043a\u0430 &#171;\u041e\u0442\u043c\u0435\u043d\u0430&#187;<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>cancelDeleteTimer<\/code><\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435 <strong>5. \u041a\u043d\u043e\u043f\u043a\u0430 &#171;\u0423\u0434\u0430\u043b\u0438\u0442\u044c&#187;<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>removeTimer<\/code><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 <strong>6. \u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>goToCreateTimer<\/code><\/p>\n<\/li>\n<li>\n<p>\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f (<code>\/timer-update\/new<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 CTA \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 <strong>7. UX-\u043b\u043e\u0433\u0438\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442 \u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e\u0432\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<hr\/>\n<h3>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u041c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u0439\u043c\u0435\u0440 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<pre><code class=\"bash\">cargo tauri dev<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 <strong>\u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u044b\u00bb<\/strong> \u0432\u044b\u0431\u0438\u0440\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u00bb<\/strong>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba6\/58c\/177\/ba658c17701715b23c4abe000ece356f.png\" alt=\"\u0422\u0430\u0439\u043c\u0435\u0440\u044b\" title=\"\u0422\u0430\u0439\u043c\u0435\u0440\u044b\" width=\"800\" height=\"599\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ba6\/58c\/177\/ba658c17701715b23c4abe000ece356f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba6\/58c\/177\/ba658c17701715b23c4abe000ece356f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0430\u0439\u043c\u0435\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u0435\u043d\u044f \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442 \u044d\u043a\u0440\u0430\u043d <strong>\u00ab\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u00bb<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412 \u043f\u043e\u043b\u0435 <strong>\u00ab\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u00bb<\/strong> \u043d\u0443\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0438\u043c\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b, \u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u0432.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u0432 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u0447\u0435\u043c \u0440\u0443\u0447\u043d\u043e\u0439 \u0432\u0432\u043e\u0434 \u0447\u0438\u0441\u0435\u043b \u0438\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u0441\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c\u0438 \u0432\u0432\u0435\u0440\u0445 \u0438 \u0432\u043d\u0438\u0437.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0442 10 \u0434\u043e 90 \u043c\u0438\u043d\u0443\u0442. \u042d\u0442\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u044b \u043d\u0430 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u0445 \u043c\u0435\u0442\u043e\u0434\u0438\u043a\u0438 Pomodoro. \u0425\u043e\u0442\u044f, \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438, \u0434\u0430\u0436\u0435 90 \u043c\u0438\u043d\u0443\u0442 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u2014 \u044d\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e\u0435 \u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/122\/b4d\/85f\/122b4d85fcf9f03609d32bd7c635b098.png\" alt=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u043d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445)\" title=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u043d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445)\" width=\"800\" height=\"1046\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/122\/b4d\/85f\/122b4d85fcf9f03609d32bd7c635b098.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/122\/b4d\/85f\/122b4d85fcf9f03609d32bd7c635b098.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u043d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445)<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043a\u0440\u043e\u043c\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u043b\u0435 <strong>\u00ab\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u00bb<\/strong>? \u041b\u044e\u0431\u0430\u044f \u0444\u043e\u0440\u043c\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u043d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c\u00bb<\/strong>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/71a\/6fc\/352\/71a6fc3529f6daeb5cf83fa7a61a4098.png\" alt=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u044e\u0437\u0435\u0440 \u043d\u0435 \u0432\u0432\u0451\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435)\" title=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u044e\u0437\u0435\u0440 \u043d\u0435 \u0432\u0432\u0451\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435)\" width=\"800\" height=\"503\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/71a\/6fc\/352\/71a6fc3529f6daeb5cf83fa7a61a4098.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/71a\/6fc\/352\/71a6fc3529f6daeb5cf83fa7a61a4098.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u044e\u0437\u0435\u0440 \u043d\u0435 \u0432\u0432\u0451\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435)<\/figcaption><\/div>\n<\/figure>\n<p>\u0424\u043e\u0440\u043c\u0430, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e: \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0432\u044b\u0432\u0435\u043b\u0430 \u043f\u043e\u0434 \u043f\u043e\u043b\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043a\u0440\u0430\u0441\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440\u044b, \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 \u0441\u043e \u0441\u0440\u0435\u0434\u043d\u0438\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0432\u043e\u0436\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0438\u0437\u043c\u0435\u043d\u044f\u044e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u0432 \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c\u00bb<\/strong>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/742\/c04\/acc\/742c04acc72d06fda4fe2c48803d230e.png\" alt=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u044b)\" title=\"\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u044b)\" width=\"800\" height=\"1038\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/742\/c04\/acc\/742c04acc72d06fda4fe2c48803d230e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/742\/c04\/acc\/742c04acc72d06fda4fe2c48803d230e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 (\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u044b)<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u043d\u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d <strong>\u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u00bb<\/strong>. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0435\u0433\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0448\u0430\u043f\u043a\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 <strong>\u00ab\u041d\u0430\u0437\u0430\u0434\u00bb<\/strong>. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ce3\/369\/0cf\/ce33690cf1b49ccc47856328fcc217d3.png\" alt=\"\u0422\u0430\u0439\u043c\u0435\u0440\" title=\"\u0422\u0430\u0439\u043c\u0435\u0440\" width=\"799\" height=\"745\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ce3\/369\/0cf\/ce33690cf1b49ccc47856328fcc217d3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ce3\/369\/0cf\/ce33690cf1b49ccc47856328fcc217d3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0430\u0439\u043c\u0435\u0440<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044f \u0445\u043e\u0447\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043a\u043d\u043e\u043f\u043a\u0438 <strong>\u00ab\u041d\u0430\u0437\u0430\u0434\u00bb<\/strong> \u0432 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u043d\u0430\u0447\u0430\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c. \u041d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u0421\u0442\u0430\u0440\u0442\u00bb<\/strong>, \u0437\u0430\u0442\u0435\u043c <strong>\u00ab\u041f\u0430\u0443\u0437\u0430\u00bb<\/strong>, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u044e <strong>\u00ab\u041d\u0430\u0437\u0430\u0434\u00bb<\/strong>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/46a\/0f6\/d29\/46a0f6d2948d160727402993ab426ad2.png\" alt=\"\u0422\u0430\u0439\u043c\u0435\u0440 (\u043d\u0430 \u043f\u0430\u0443\u0437\u0435 + \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u041d\u0430\u0437\u0430\u0434)\" title=\"\u0422\u0430\u0439\u043c\u0435\u0440 (\u043d\u0430 \u043f\u0430\u0443\u0437\u0435 + \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u041d\u0430\u0437\u0430\u0434)\" width=\"802\" height=\"759\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/46a\/0f6\/d29\/46a0f6d2948d160727402993ab426ad2.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/46a\/0f6\/d29\/46a0f6d2948d160727402993ab426ad2.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0430\u0439\u043c\u0435\u0440 (\u043d\u0430 \u043f\u0430\u0443\u0437\u0435 + \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u041d\u0430\u0437\u0430\u0434)<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u043e\u043a\u043d\u043e \u0441 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0431\u0440\u043e\u0448\u0435\u043d. \u0415\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c <strong>\u00ab\u041d\u0435\u0442\u00bb<\/strong>, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0435. \u042f \u0436\u0435 \u043d\u0430\u0436\u0438\u043c\u0430\u044e <strong>\u00ab\u0414\u0430\u00bb<\/strong>, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0439\u0442\u0438.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/451\/fe9\/5a4\/451fe95a4af472601dd8ce4f4c0b0893.png\" alt=\"\u0422\u0430\u0439\u043c\u0435\u0440\u044b\" title=\"\u0422\u0430\u0439\u043c\u0435\u0440\u044b\" width=\"805\" height=\"668\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/451\/fe9\/5a4\/451fe95a4af472601dd8ce4f4c0b0893.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/451\/fe9\/5a4\/451fe95a4af472601dd8ce4f4c0b0893.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u0430\u0439\u043c\u0435\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0441\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d <strong>\u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u044b\u00bb<\/strong>, \u0433\u0434\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 <strong>Timer middle<\/strong>. \u0420\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u044e \u0435\u0433\u043e \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u00bb<\/strong>.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5a7\/b0e\/4e9\/5a7b0e4e9372a86420f5da9f17082ac8.png\" alt=\"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\" title=\"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\" width=\"801\" height=\"1046\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/5a7\/b0e\/4e9\/5a7b0e4e9372a86420f5da9f17082ac8.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5a7\/b0e\/4e9\/5a7b0e4e9372a86420f5da9f17082ac8.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u043e\u0440\u043c\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438, \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u0442 \u0436\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0447\u0442\u043e \u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0435\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0443 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0436\u043c\u0443 \u043a\u043d\u043e\u043f\u043a\u0443 <strong>\u00ab\u041d\u0430\u0437\u0430\u0434\u00bb<\/strong>.<\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u2014 <strong>\u00ab\u0423\u0434\u0430\u043b\u0438\u0442\u044c\u00bb<\/strong>. \u041d\u0430\u0436\u0438\u043c\u0430\u044e \u0435\u0451 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/35e\/5b2\/992\/35e5b29923070d4ed1eb08bd746beda5.png\" alt=\"\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\" title=\"\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\" width=\"802\" height=\"695\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/35e\/5b2\/992\/35e5b29923070d4ed1eb08bd746beda5.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/35e\/5b2\/992\/35e5b29923070d4ed1eb08bd746beda5.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435, \u043b\u0438\u0431\u043e \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e. \u042d\u0442\u043e \u0437\u0430\u0449\u0438\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u043d\u0430\u0436\u0430\u0442\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0431\u0451\u043d\u043a\u043e\u043c \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043a\u043e\u0442\u043e\u043c.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0443\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u044f \u0441\u0447\u0438\u0442\u0430\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439. \u041e\u0434\u043d\u0430\u043a\u043e \u0443 \u043c\u0435\u043d\u044f \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0438\u0434\u0435\u0439 \u043f\u043e \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c\u0443 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<hr\/>\n<h3>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435?<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u044b Pomodoro. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u0432\u0441\u0451 \u0435\u0449\u0451 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043d\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0435 \u0433\u0438\u0431\u043a\u043e \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<p><strong>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>\u0422\u0435\u043c\u0430<\/strong> \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0438 \u0442\u0451\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u0430\u043c\u0438 \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0437\u0432\u0443\u043a\u0430<\/strong> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043c\u0435\u043b\u043e\u0434\u0438\u044e;<\/p>\n<\/li>\n<li>\n<p><strong>\u041e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435<\/strong> \u2014 \u0440\u0430\u0437\u043c\u0435\u0449\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0430\u0432\u0442\u043e\u0440\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f MVP 1.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u044b\u0441\u043b\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u2014 \u0441 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u043b\u044e\u0441\u044c \u0441 \u0432\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438!<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u0435!<\/p>\n<hr\/>\n<h3>\u0421\u0441\u044b\u043b\u043a\u0438 \u043a \u0441\u0442\u0430\u0442\u044c\u0435<\/h3>\n<ul>\n<li>\n<p><a href=\"https:\/\/pressanybutton.ru\/user\/Arduinum628\/\" rel=\"noopener noreferrer nofollow\">\u041c\u043e\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 Arduinum628<\/a> \u043d\u0430 <a href=\"https:\/\/pressanybutton.ru\/\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u0434 \u043d\u0430 \u0441\u0430\u043b\u0444\u0435\u0442\u043a\u0435<\/a>;<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Github <a href=\"https:\/\/github.com\/Arduinum\/kawai-focus-v2\" rel=\"noopener noreferrer nofollow\">kawai-focus-v2<\/a>.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Gitverse <a href=\"https:\/\/gitverse.ru\/Arduinum628\/kawai-focus-v2\" rel=\"noopener noreferrer nofollow\">kawai-focus-v2<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1044224\/\">https:\/\/habr.com\/ru\/articles\/1044224\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041e\u0431\u043b\u043e\u0436\u043a\u0430\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435\u0412\u0441\u0435\u043c \u0434\u043e\u0431\u0440\u043e\u0433\u043e \u0434\u043d\u044f! \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u041a\u0430\u0432\u0430\u0439-\u0424\u043e\u043a\u0443\u0441 2.7: \u043f\u0443\u0442\u044c \u043a MVP1 \u2014 \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0437\u0432\u0443\u043a\u0430:\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0437\u0432\u0443\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 Web Audio API;\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0438\u0437 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432 \u0434\u043b\u044f Pomodoro.\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u044f \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u044d\u043a\u0440\u0430\u043d \u00ab\u0422\u0430\u0439\u043c\u0435\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u043e\u0431\u0440\u0430\u0437\u0446\u044b \u0441\u0435\u0441\u0441\u0438\u0439, \u043d\u0430\u0441\u0442\u0443\u043f\u0438\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0435\u043c\u0443 \u0443\u0434\u043e\u0431\u043d\u044b. \u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u044f \u043d\u0430\u043f\u0438\u0448\u0443 \u044d\u043a\u0440\u0430\u043d-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0442\u0430\u0439\u043c\u0435\u0440.\u0412\u0441\u0435 \u043d\u043e\u0432\u044b\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 SQLite3, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u0422\u0430\u043a\u0436\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041a \u043d\u043e\u0432\u043e\u043c\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0443 \u043a\u043d\u043e\u043f\u043a\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u043c\u0438.\u0417\u0430\u0432\u0430\u0440\u0438\u0432\u0430\u0439\u0442\u0435 \u0447\u0430\u0439, \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043a\u0443\u0441\u043d\u044f\u0448\u043a\u0438 \u2014 \u043f\u043e\u0440\u0430 \u00ab\u0432\u044b\u0441\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0433\u0440\u044f\u0434\u043a\u0438 \u0438\u0437 \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u043e\u0432\u00bb! \ud83c\udf45Crud \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u2014 \u043d\u0430\u043f\u0438\u0448\u0443 CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u0442\u0440\u043e\u043a\u0438 DML-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u043d\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e: \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c, \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u044b.timerDML.ts\u0420\u0430\u0441\u0448\u0438\u0440\u044e \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043d\u043e\u0432\u044b\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0411\u0414.export const INSERT_TIMER = &#8216;INSERT INTO timer (title, pomodoro_time, break_time, break_long_time, count_pomodoro) VALUES (?, ?, ?, ?, ?)&#8217;INSERT_TIMER \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 timer,\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: title, pomodoro_time, break_time, break_long_time, count_pomodoro,\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u043b\u0435\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b ? \u0434\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.export const UPDATE_TIMER = &#8216;UPDATE timer SET title = ?, pomodoro_time = ?, break_time = ?, break_long_time = ?, count_pomodoro = ? WHERE id = ?&#8217;UPDATE_TIMER \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430,\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e id,\u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0439.export const DELETE_TIMER = &#8216;DELETE FROM timer WHERE id = ?&#8217;DELETE_TIMER \u2014 SQL-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b timer \u043f\u043e id,\u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 \u0442\u0440\u0451\u0445, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0414\u0430\u043b\u0435\u0435 \u044d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432 CRUD-\u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445.timerCrud.ts\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0443 \u0441\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f CRUD-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442 timerDML.ts, \u0442\u0430\u043a \u043a\u0430\u043a \u0438 \u0442\u0430\u043a \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043e\u043d \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d.\/** \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function createTimer(  title: string,   pomodoroTime: number,   breakTime: number,   breakLongTime: number,   countPomodoro: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(INSERT_TIMER, [    title,     pomodoroTime,     breakTime,     breakLongTime,     countPomodoro  ]);}createTimer \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438\u0437 UI,\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0411\u0414 \u0447\u0435\u0440\u0435\u0437 getDb(),\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 INSERT_TIMER,\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 QueryResult (\u0432\u043a\u043b\u044e\u0447\u0430\u044f lastInsertId).\/** \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function updateTimer(  TimerId: number,  title: string,  pomodoroTime: number,  breakTime: number,  breakLongTime: number,  countPomodoro: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(UPDATE_TIMER, [    title,    pomodoroTime,    breakTime,    breakLongTime,    countPomodoro,    TimerId  ]);}updateTimer \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 TimerId \u0438 \u043d\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f,\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 UPDATE_TIMER,\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u043e id, \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043d\u043e\u0432\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c.\/** \u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 *\/export async function deleteTimer(  TimerId: number): Promise&lt;QueryResult&gt; {  const db = await getDb();  return await db.execute(DELETE_TIMER, [TimerId]);}deleteTimer \u2014 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430:\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e TimerId,\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 DELETE_TIMER,\u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u0438\u0437 \u0431\u0430\u0437\u044b.\u041d\u043e\u0432\u044b\u0435 CRUD-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0433\u043e\u0442\u043e\u0432\u044b, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e view \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.TimerUpdate\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d view TimerUpdate, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u043e\u043b\u044c \u0444\u043e\u0440\u043c\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043e\u0434\u0438\u043d view \u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f, \u0438 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u0434\u0430 \u0438 \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0432\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.\u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0443\u0442\u0438\u043d\u043d\u044b\u0435 \u0432\u0435\u0449\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0441\u0442\u0438\u043b\u0438 CSS \u0438\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u043e\u0443\u0442\u043e\u0432, \u0438 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0443\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0435\u0433\u043e HTML.TimerUpdate.ts\u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 view, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b \u0438 \u0442.\u0434.import { computed, defineComponent, onMounted, ref, watch } from &#8216;vue&#8217;;import { IonIcon, IonPage, IonContent } from &#8216;@ionic\/vue&#8217;;import { useRoute, useRouter } from &#8216;vue-router&#8217;;import { arrowBackOutline, checkmarkOutline } from &#8216;ionicons\/icons&#8217;;import { createTimer, getTimer, updateTimer } from &#8216;@\/db\/crud\/timerCrud&#8217;;import type { TimerRow } from &#8216;@\/types\/timerType&#8217;;const LIMITS = {  pomodoroTime: { min: 10, max: 90 },  breakTime: { min: 3, max: 10 },  breakLongTime: { min: 15, max: 40 },  countPomodoro: { min: 2, max: 8 },} as const;export default defineComponent({  name: &#8216;TimerUpdate&#8217;,  components: { IonIcon, IonPage, IonContent },  setup() {    const route = useRoute();    const router = useRouter();    const isCreateMode = computed(() =&gt; route.params.id = &#8216;new&#8217;);    const currentId = computed(() =&gt; (isCreateMode.value ? 0 : Number(route.params.id)));    const loading = ref(false);    const error = ref&lt;string | null&gt;(null);    const titleError = ref(&#187;);    const modeLabel = computed(() =&gt; (isCreateMode.value ? &#8216;\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440&#8217; : &#8216;\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440&#8217;));    const form = ref&lt;TimerRow&gt;({      id: currentId.value,      title: &#187;,      pomodoro_time: LIMITS.pomodoroTime.min,      break_time: LIMITS.breakTime.min,      break_long_time: LIMITS.breakLongTime.min,      count_pomodoro: LIMITS.countPomodoro.min,    });    \/**     * \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0447\u0438\u0441\u043b\u043e.     * \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.     *\/    const safeNumber = (value: unknown, fallback: number): number =&gt; {      const parsed = Number(value);      return Number.isFinite(parsed) ? parsed : fallback;    };    \/**     * \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c min-max.     *\/    const clamp = (value: number, min: number, max: number): number =&gt; {      return Math.min(max, Math.max(min, value));    };    \/**     * \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f     * \u043a \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.     *\/    const normalizeTimer = (timer?: Partial&lt;TimerRow&gt;): TimerRow =&gt; {      return {        id: currentId.value,        title: timer?.title ?? &#187;,        pomodoro_time: clamp(safeNumber(timer?.pomodoro_time, LIMITS.pomodoroTime.min), LIMITS.pomodoroTime.min, LIMITS.pomodoroTime.max),        break_time: clamp(safeNumber(timer?.break_time, LIMITS.breakTime.min), LIMITS.breakTime.min, LIMITS.breakTime.max),        break_long_time: clamp(safeNumber(timer?.break_long_time, LIMITS.breakLongTime.min), LIMITS.breakLongTime.min, LIMITS.breakLongTime.max),        count_pomodoro: clamp(safeNumber(timer?.count_pomodoro, LIMITS.countPomodoro.min), LIMITS.countPomodoro.min, LIMITS.countPomodoro.max),      };    };    \/**     * \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u0444\u043e\u0440\u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c.     *\/    const clampField = (field: keyof TimerRow, min: number, max: number): void =&gt; {      if (typeof form.value[field] = &#8216;number&#8217;) {        form.value[field] = clamp(safeNumber(form.value[field], min), min, max) as never;      }    };    \/**     * \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u0430.     *\/    const onSliderInput = (field: keyof TimerRow, min: number, max: number, value: Event): void =&gt; {      const nextValue = safeNumber((value.target as HTMLInputElement | null)?.value, min);      if (typeof form.value[field] = &#8216;number&#8217;) {        form.value[field] = clamp(nextValue, min, max) as never;      }    };    \/**     * \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u0437 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u0431\u043e     * \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0444\u043e\u0440\u043c\u0443 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.     *\/    const loadTimer = async (): Promise&lt;void&gt; =&gt; {      if (isCreateMode.value) {        form.value = normalizeTimer({          id: 0,          title: &#187;,          pomodoro_time: LIMITS.pomodoroTime.min,          break_time: LIMITS.breakTime.min,          break_long_time: LIMITS.breakLongTime.min,          count_pomodoro: LIMITS.countPomodoro.min,        });        return;      }      loading.value = true;      error.value = null;      try {        const timer = await getTimer(currentId.value);        form.value = normalizeTimer(timer);      } catch (e) {        error.value = e instanceof Error ? e.message : &#8216;\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430&#8217;;      } finally {        loading.value = false;      }    };    \/**     * \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430.     *\/    const validateTitle = (): boolean =&gt; {      const trimmedTitle = form.value.title.trim();      if (!trimmedTitle) {        titleError.value = &#8216;\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430&#8217;;        return false;      }      titleError.value = &#187;;      return true;    };    \/**     * \u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u0442\u0430\u0439\u043c\u0435\u0440 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439.     *\/    const saveTimer = async (): Promise&lt;void&gt; =&gt; {      if (!validateTitle()) {        return;      }      try {        const trimmedTitle = form.value.title.trim();        form.value = normalizeTimer({          id: isCreateMode.value ? 0 : currentId.value,          title: trimmedTitle,          pomodoro_time: form.value.pomodoro_time,          break_time: form.value.break_time,          break_long_time: form.value.break_long_time,          count_pomodoro: form.value.count_pomodoro,        });        if (isCreateMode.value) {          const result = await createTimer(            form.value.title,            form.value.pomodoro_time,            form.value.break_time,            form.value.break_long_time,            form.value.count_pomodoro,          );          const newId = Number((result as { lastInsertId?: number }).lastInsertId ?? 0);          if (!newId) {            throw new Error(&#8216;\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c id \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430&#8217;);          }          router.push(`\/timer\/${newId}`);          return;        }        await updateTimer(          currentId.value,&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-482575","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=482575"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482575\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=482575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=482575"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=482575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}