{"id":359817,"date":"2024-05-21T00:40:30","date_gmt":"2024-05-21T00:40:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=359817"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T00:40:30","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=359817","title":{"rendered":"<span>\u0420\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u0434\u0430\u0447\u0438 B (\u0411\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0443\u0437\u044b\u043a\u0430) \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u2014 Yandex Cup 2023 \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/870\/021\/83f\/87002183f375069f1e8998b3698302ee.png\" alt=\"\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u043a Yandex Cup 2023\" title=\"\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u043a Yandex Cup 2023\" width=\"625\" height=\"197\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/870\/021\/83f\/87002183f375069f1e8998b3698302ee.png\"\/><\/p>\n<div><figcaption>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u043a Yandex Cup 2023<\/figcaption><\/div>\n<\/figure>\n<p>\u0423\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0434\u0430\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u043f\u0438\u043d\u043e\u043a \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0442\u043e, \u0447\u0442\u043e \u0435\u0449\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0438\u0440\u0435 JS \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e. \u0412\u043e\u0442 \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u0432 \u044d\u0442\u043e\u043c \u0433\u043e\u0434\u0443, \u0432\u0441\u0435 \u0436\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0430\u0440\u0443 \u0442\u0440\u043e\u0439\u043a\u0443 \u0437\u0430\u0434\u0430\u0447. \u0418 \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0440\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u043e \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0438\u0442\u0447\u0443 \u0432 JS &#8212; \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0439\u0441\u044f \u043a \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c. <\/p>\n<hr\/>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u044f \u0440\u0430\u043d\u0435\u0435 \u0441\u043b\u044b\u0448\u0430\u043b \u043f\u0440\u043e \u0442\u043e, \u0447\u0442\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430\u0442\u0438\u0432\u043d\u043e, &#171;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&#187;, \u0432 JS. \u0422\u0430\u043a\u0430\u044f \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u0438\u043a\u0430 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0430 \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0432 \u043f\u0438\u0442\u043e\u043d\u0435. \u041d\u0443 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b, \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u0434\u0443 \u0431\u044b\u0442\u044c \u043b\u0443\u0447\u0448\u0435 \u0438 \u0432 \u043f\u043b\u0430\u043d\u0435 \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u0437 TypeScript \u0432 JavaScript.<\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0432 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u043d\u044b\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u0435\u043b \u0432 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u041f\u043e\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e, \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0435\u043c \u0435\u0441\u043b\u0438 \u0431\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0432\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 &#171;\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0438\u0447\u0438&#187; \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u0418 \u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 B &#8212; &#171;\u0411\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0443\u0437\u044b\u043a\u0430&#187;<\/summary>\n<div class=\"spoiler__content\">\n<h2>B. \u0411\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0443\u0437\u044b\u043a\u0430 (20 \u0431\u0430\u043b\u043b\u043e\u0432)<\/h2>\n<p>\u041e\u0434\u043d\u0430\u0436\u0434\u044b \u0426\u0430\u043d\u0441 \u0425\u0438\u043c\u043c\u0435\u0440, \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440 XII \u0432\u0435\u043a\u0430, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0430\u0443\u043d\u0434\u0442\u0440\u0435\u043a\u0430\u043c\u0438 \u043a \u0444\u0438\u043b\u044c\u043c\u0430\u043c, \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043f\u0438\u0448\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u043c\u0443\u0437\u044b\u043a\u0443, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0435\u0451 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043d\u0435\u0432\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043f\u0435\u0440\u0444\u043e\u0440\u043c\u0430\u043d\u0441 \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0430 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0435 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0426\u0430\u043d\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0441\u044b\u0433\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0451 \u0443\u0436\u0435 \u0441\u0442\u0430\u0432\u0448\u0435\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 Time \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u043d\u0430 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0442\u0435 \u0437\u0432\u0443\u043a\u0438, \u0447\u0442\u043e \u0438\u0437\u0434\u0430\u0451\u0442 \u0435\u0433\u043e \u0444\u043e\u0440\u0442\u0435\u043f\u0438\u0430\u043d\u043e.<\/p>\n<p>\u0412\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0442\u044b \u0432 \u0446\u0432\u0435\u0442\u0430 \u043f\u0430\u043b\u0438\u0442\u0440\u044b OKLCH, \u0447\u0442\u043e\u0431\u044b \u043c\u0430\u0441\u0442\u0435\u0440 \u0441\u043c\u043e\u0433 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0435.<\/p>\n<h3>\u0423\u0441\u043b\u043e\u0432\u0438\u0435<\/h3>\n<p>\u0426\u0432\u0435\u0442\u0430 \u0432 OKLCH \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: &#171;48% 0.27 274 \/ 1&#187; (L C H \/ a)<\/p>\n<p>\u0412\u0438\u0434\u0438\u043c\u044b\u0435 \u0446\u0432\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u0445 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432\u00a0<a href=\"https:\/\/web-standards.ru\/articles\/oklch-in-css-why-quit-rgb-hsl\/#section-1\" rel=\"noopener noreferrer nofollow\">https:\/\/web-standards.ru\/articles\/oklch-in-css-why-quit-rgb-hsl\/#section-1<\/a>):<\/p>\n<ul>\n<li>\n<p>L \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 100% (\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430\u0445)<\/p>\n<\/li>\n<li>\n<p>C \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 0.37<\/p>\n<\/li>\n<li>\n<p>H \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 360<\/p>\n<\/li>\n<li>\n<p>a \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 1<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b @Color \u0438 @ColorPlayer, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0436\u0443\u0442 \u0438\u0433\u0440\u0443 \u043d\u043e\u0442 \u0441 \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 @Color:<\/p>\n<p>@Color(&#171;L&#187;, &#171;10%&#187;) playA(octave)<\/p>\n<p>@Color(&#171;\u0421&#187;, &#171;0.11&#187;) playB(octave)<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 playA (\u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c) \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043a\u0442\u0430\u0432\u043e\u0439 octave (\u043e\u0442 0 \u0434\u043e 8), \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 L \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u043d\u0430 L + (octave &#8212; 3) * 10 (\u0442\u0430\u043a \u043a\u0430\u043a L \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430\u0445).<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 playB \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043a\u0442\u0430\u0432\u043e\u0439 octave (\u043e\u0442 0 \u0434\u043e 8), \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 C \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u043d\u0430 C + (octave &#8212; 3) * 0.11.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422.\u0435. \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u0438\u043c\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043a\u0442\u0430\u0432\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u043e\u043a\u0442\u0430\u0432\u044b (\u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439). \u0412\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0435\u0435\u0441\u044f \u0447\u0438\u0441\u043b\u043e \u043e\u043a\u0440\u0443\u0433\u043b\u044f\u0435\u043c \u0434\u043e \u0434\u0432\u0443\u0445 \u0437\u043d\u0430\u043a\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f .toFixed(2).<\/p>\n<p>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 @ColorPlayer \u0437\u0430\u0434\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043a\u043e\u043b\u0431\u044d\u043a, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 (\u0432\u044b\u0437\u043e\u0432 play*) \u0438 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0434 \u0432\u0441\u0435\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code>@ColorPlayer(\"48% 0.27 274 \/ 1\", (color) => console.log(color)) class Piano {     @Color(\"L\", \"10%\")     playA(octave) {} @Color(\"C\", \"0.15\") playB(octave) {}  @Color(\"H\", \"0.03\") playC(octave) {}  @Color(\"L\", \"10%\") playD(octave) {}  @Color(\"C\", \"0.15\") playE(octave) {}  @Color(\"H\", \"0.1\") playF(octave) {}  @Color(\"a\", \"0.4\") playG(octave) {}  } <\/code><\/pre>\n<pre><code>const piano = new Piano(); \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playA(2) \/\/ console.log(\"38.00% 0.27 274.00 \/ 1.00\") piano.playA(4) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playB(3) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") <\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438:<\/p>\n<pre><code>export function ColorPlayer(initialColor, cb) { } <\/code><\/pre>\n<pre><code>export function Color(component, coeff) { } <\/code><\/pre>\n<p><em>\u0412\u0430\u0436\u043d\u043e<\/em>: \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e 2023 \u0433\u043e\u0434\u0430\u00a0<a href=\"https:\/\/github.com\/tc39\/proposal-decorators\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/tc39\/proposal-decorators<\/a>\u00a0\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f babel. \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442\u00a0<a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/531664\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/otus\/articles\/531664\/<\/a>, \u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 2023 \u0433\u043e\u0434\u0430 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0432\u044b\u0448\u0435.<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0438\u0447\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432, &#171;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&#187;, \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0438\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 <strong>20<\/strong> \u0438\u0437 <strong>20<\/strong> \u0431\u0430\u043b\u043b\u043e\u0432.<\/p>\n<details class=\"spoiler\">\n<summary>package.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>{   \"name\": \"project\",   \"version\": \"1.0.0\",   \"description\": \"\",   \"main\": \"index.js\",   \"scripts\": {     \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\",     \"build\": \"babel src -d lib\",     \"start\": \"babel src -d lib &amp;&amp; node lib\/index.js\"   },   \"keywords\": [],   \"author\": \"\",   \"license\": \"ISC\",   \"devDependencies\": {     \"@babel\/cli\": \"^7.23.0\",     \"@babel\/core\": \"^7.23.2\",     \"@babel\/plugin-proposal-decorators\": \"^7.23.2\",     \"@babel\/preset-env\": \"^7.23.2\"   } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>babel.config.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>{     \"presets\": [         \"@babel\/preset-env\"     ],     \"plugins\": [         [             \"@babel\/plugin-proposal-decorators\",             {                \"version\": \"2023-05\"             }         ]     ] }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430, \u043a\u0430\u043a \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0438\u0436\u0435:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/babeljs.io\/docs\/babel-plugin-proposal-decorators\" rel=\"noopener noreferrer nofollow\">@babel\/plugin-proposal-decorators \u00b7 Babel (babeljs.io)<\/a>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#classes\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes (github.com)<\/a>  <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#class-fields\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes class-fields (github.com)<\/a>  <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#example-customelement\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes customelement (github.com)<\/a>  <\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0446\u0432\u0435\u0442\u0430 \u0432 \u043d\u043e\u0442\u0430\u0446\u0438\u0438 (L C H \/ a)  <\/h3>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0438 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <em>InitialColor<\/em>. \u041d\u043e \u0432 \u0437\u0430\u0434\u0430\u0447\u0435, \u0442\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u0447\u0435\u0441\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0439\u0442\u0438 \u0447\u0438\u0441\u043b\u043e, \u043d\u043e \u043d\u0435 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u043b\u0438\u0431\u043e \u043d\u0438\u0436\u043d\u044e\u044e \u0433\u0440\u0430\u043d\u0438\u0446\u0443, \u043b\u0438\u0431\u043e \u0432\u0435\u0440\u0445\u043d\u044e\u044e, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0443\u0434\u0430 \u0443\u0441\u0442\u0440\u0435\u043c\u0438\u043b\u043e\u0441\u044c \u043d\u043e\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u0412 \u044d\u0442\u043e\u043c \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 <em>\u0433\u0435\u0442\u0442\u0435\u0440\u044b<\/em> \u0438 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u044b<\/em> \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043d\u0438\u0436\u0435, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043a\u043e\u0434 <em>\u0433\u0435\u0442\u0442\u0435\u0440\u0430<\/em> \u0438 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u0430<\/em> \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>L<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 <em>InitialColor:<\/em><\/p>\n<pre><code class=\"javascript\">... get L() {     return this.Lv }  set L(v) {     if (v &lt; 0 || v > 100) {         this.Lv = Math.min(100, Math.max(0, v))     } else {         this.Lv = v     } } ...<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u044e\u043a \u0441 min\/max.<\/p>\n<pre><code class=\"javascript\">Math.min(100 \/* \u0447\u0438\u0441\u043b\u043e_\u0432\u0435\u0440\u0445\u043d\u0435\u0439_\u0433\u0440\u0430\u043d\u0438\u0446\u044b *\/, Math.max(0 \/* \u0447\u0438\u0441\u043b\u043e_\u043d\u0438\u0436\u043d\u0435\u0439_\u0433\u0440\u0430\u043d\u0438\u0446\u044b *\/, v))<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043d\u0443\u0436\u043d\u043e \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. <\/p>\n<pre><code class=\"javascript\">class InitialColor {     constructor(value) {         const [Lv, Cv, Hv, ,av] = value.split(' ')         this.Lv = parseFloat(Lv)         this.Cv = parseFloat(Cv)         this.Hv = parseFloat(Hv)         this.av = parseFloat(av)     }        ... }<\/code><\/pre>\n<p>\u0418 \u0435\u0449\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e, \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>toString()<\/code>.<\/p>\n<pre><code class=\"javascript\">class InitialColor {     \/\/ ...     toString() {         return `${this.L.toFixed(2)}% ${this.C.toFixed(2)} ${this.H.toFixed(2)} \/ ${this.a.toFixed(2)}`     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 ColorPlayer <\/h3>\n<p>\u0414\u043b\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430 <em>Color<\/em>, \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0432\u0435\u0442\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <em>ColorPlayer<\/em>. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0432 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u0440\u044e\u043a, \u043c\u043e\u0436\u043d\u043e \u043b\u0438\u0448\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0442 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u043c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043d\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439, \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u0431\u0435\u0437 \u0432\u0440\u0435\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430 <em>ColorPlayer<\/em>:<\/p>\n<pre><code class=\"javascript\">export function ColorPlayer(initialColor \/*\u0446\u0432\u0435\u0442*\/, cb \/*\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f*\/) {     \/\/ ...     return function decorator(target, { kind, addInitializer }) {         if (kind === 'class') {             \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442 target             return class extends target {                 cb = cb \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441 \u043a\u043e\u043b\u0431\u0435\u043a\u043e\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f                 initialColor = new InitialColor(initialColor) \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0446\u0432\u0435\u0442\u0430                 constructor() {                     super(...arguments)                     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e)                     cb(new InitialColor(initialColor).toString())                 }             }         }     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <code>cb<\/code>  \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>initialColor<\/em> (\u0434\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0438 \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043a\u043b\u0430\u0441\u0441\u0430):<\/p>\n<pre><code class=\"javascript\">cb(new InitialColor(initialColor).toString())<\/code><\/pre>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 Color<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0435, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043d\u0430\u0434 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 <em>initialColor<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0443 <em>ColorPlayer, <\/em>\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u043a\u043e\u0434 \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"javascript\">export function Color(component, coeff) {     return function (fn, { kind }) {         if (kind === 'method') {             return function (octave) {                 this.initialColor[component] += ((parseFloat(octave) - 3) * parseFloat(coeff))                 this.cb(this.initialColor.toString())                 fn.call(this, octave)             }         }         return fn     } }<\/code><\/pre>\n<p>\u041f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e, \u0432 \u0437\u0430\u0434\u0430\u0447\u0435 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u043a\u0442\u0430\u0432\u044b \u043d\u0430 3 \u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442. \u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 InitialColor \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u044b<\/em>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u044b \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b, \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443, \u043a\u0430\u043a \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>this.initialColor[component] += ((parseFloat(octave) - 3) * parseFloat(coeff))<\/code><\/pre>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435, \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>initialColor<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>cb<\/code> , \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u0442\u044c, \u0441\u0430\u043c\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0447\u0435\u0440\u0435\u0437 <code>fn.call(this, octave)<\/code>.<\/p>\n<p>\u041d\u0443 \u0432\u043e\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 <strong>20<\/strong> \u0438\u0437 <strong>20<\/strong> \u0431\u0430\u043b\u043b\u043e\u0432.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438 \u044f \u0435\u0433\u043e \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0438\u0436\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043a\u043e\u0440\u043e\u0430\u0442\u043e\u0440\u0432 ColorPlayer \u0438 Color (decorators.js)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">export function ColorPlayer(initialColor, cb) {     class InitialColor {         constructor(value) {             const [Lv, Cv, Hv, ,av] = value.split(' ')             this.Lv = parseFloat(Lv)             this.Cv = parseFloat(Cv)             this.Hv = parseFloat(Hv)             this.av = parseFloat(av)         }          get L() {             return this.Lv         }          set L(v) {             if (v &lt; 0 || v > 100) {                 this.Lv = Math.min(100, Math.max(0, v))             } else {                 this.Lv = v             }         }          get C() {             return this.Cv         }          set C(v) {             if (v &lt; 0 || v > 0.37) {                 this.Cv = Math.min(0.37, Math.max(0, v))             } else {                 this.Cv = v             }         }          get H() {             return this.Hv         }          set H(v) {             if (v &lt; 0 || v > 360) {                 this.Hv = Math.min(360, Math.max(0, v))             } else {                 this.Hv = v             }         }          get a() {             return this.av         }          set a(v) {             if (v &lt; 0 || v > 1) {                 this.av = Math.min(1, Math.max(0, v))             } else {                 this.av = v             }         }          toString() {             return `${this.L.toFixed(2)}% ${this.C.toFixed(2)} ${this.H.toFixed(2)} \/ ${this.a.toFixed(2)}`         }     }     return function decorator(target, { kind, addInitializer }) {         if (kind === 'class') {             return class extends target {                 cb = cb                 initialColor = new InitialColor(initialColor)                 constructor() {                     super(...arguments)                     cb(new InitialColor(initialColor).toString())                 }             }         }     } }  export function Color(component, coeff) {     return function (fn, { kind }) {         if (kind === 'method') {             return function (octave) {                 this.initialColor[component] += ((parseFloat(octave) - 3) * parseFloat(coeff))                 this.cb(this.initialColor.toString())                 fn.call(this, octave)             }         }         return fn     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 (index.js)<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\">import { ColorPlayer, Color } from '.\/decorators'  @ColorPlayer(\"48% 0.27 274 \/ 1\", (color) => console.log(color))  class Piano {     @Color(\"L\", \"10%\")     playA(octave) {         console.log(\"A\" + octave);     }      @Color(\"C\", \"0.15\")     playB(octave) {         console.log(\"B\" + octave)     }      @Color(\"H\", \"0.03\")     playC(octave) {         console.log(\"C\" + octave);     }      @Color(\"L\", \"10%\")     playD(octave) { }      @Color(\"C\", \"0.15\")     playE(octave) { }      @Color(\"H\", \"0.1\")     playF(octave) { }      @Color(\"a\", \"0.4\")     playG(octave) { } }  const piano = new Piano(); \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playA(2) \/\/ console.log(\"38.00% 0.27 274.00 \/ 1.00\") piano.playA(4) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playB(3) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") console.log('-------------------------------------') const piano2 = new Piano(); \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano2.playA(2) \/\/ console.log(\"38.00% 0.27 274.00 \/ 1.00\") piano2.playA(4) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano2.playB(3) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\")<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a, \u044f \u043f\u043e\u0449\u0443\u043f\u0430\u043b \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u0431\u0443\u0434\u0443 \u0441 \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0437\u0430 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u043c\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438 \u0438 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435\u043c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 JS. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u042f\u043d\u0434\u0435\u043a\u0441\u0443 \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0433\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043c\u043e\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u0435\u043d.<\/p>\n<p><strong>P.S.<\/strong>: \u0410 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0441 \u043a\u043e\u0434\u043e\u043c \u043e\u043d\u043b\u0430\u0439\u043d, \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 <a href=\"https:\/\/babeljs.io\/repl#?browsers=&amp;build=&amp;builtIns=usage&amp;corejs=3.21&amp;spec=false&amp;loose=true&amp;code_lz=AIYQ9gNmBOAKEEMCeBTaAKARAFgBwFIACABgDoAmAdkKu0IHpCBGTAGkPQGNIYBKQgLwA-QtwB2AZ0gpSUAOZce0XrwBQnRBImFYASwRiwhAN6rC5wqCVYAMm0KYmxfJjUXCAB0RIAgujCcAC4IAG4o_KbuAJDiUhAy8lg-mIQA1IQBwWG8ANxmFgC-qvnmVlAYmCD2mGRMAKyuJZ7eAEL-QaHhJk0xYJLSsmAKmC0p6ZmdboWExe5lMFgAEtVkxADMje5eyCDtWV2RFr398YPDVWkZHdl57kVN8xV27I7OmxbbSAAie5Mm93NwOUsFUXrUGlNzJ8AKK_bL_WYWR5LFakFiQ5rIABicIORXMDyBC0wCFR2HeUO8AHFcREivjVAAzACuYiCuj6hCJcG8aHQujEukC-gg3PYnAARhEmhoEFpCABJQXChCipTddzuWKBaDMoILEKq5kHJqaizawgAbRsIXYIFthEWDtYoQAuoJCIaIMbSBIvEL0AByQiBjFm8yBAAWugkpBtHo8CGgEhQWKgCEC6BtYfDUZjpHtCaTKbTYAz6HtObNedjTqLydT6czTqrmprpFC9ZLTfQoVbAPDchQgUINnQ0vDmugw-Z0DEhHbNtNhURZpTI7HIQnk4sukZHBChAAPCRCAAfM-ewgiJzEbc7tvR2PxgSEACyGcjpAAtgL0Lf2A_KMfwQAAPdBiHYLdWzuQgUAgFMNQfR98xfT1lzNfFwwHM0hxHXZ7x3adAlned23tDDCBwzV1y5dAtyQh89wPY9TwvK8RDINZKEI5CFyfAtD1fICv1_MQINIbjAM_EDwMgz0VEo2D4MQw4-IjATC1fEIlJXSdqPcPDHXHRiiJnOd-PzJ1KIMixaMWejePDZj6NY4hz0vQ8RDWAA2O9TL49s62EmSxPQXz5JE2SIKgxS-IKOCEJQALkKCoT0PimzV01IyEBMtSzJIiz21CLLKNovKGIKycXMPE93PYrzmCch8SvSqKwqYaTgO_MCYoUmDphU5LqtSgTO203TzCwzDsvcQIwAAZR1AUFBaqdzPnAADAASYxF1IBasV0UCUAAE3QcheAKIg9vIw6wGO06LquhK7oExYHqe87LuuhhCHe_MEC-k6fterasruJpiNIwgWTZYVOTOlBuGgDMFmCaA8PYYxCAAawFM72AQM6zqVIURV0AAvNAqPWlyCbEM7BAEV9A1lLRQxSs0YYsjntBQUDAhQJntExozRofSUPUlKbNQFCnVW5D0xBQAB3RVlRFbl-S1pWlEGs1tV1fUMHWviJGZDw-VIW2kzkZlvxFwIJENndJXQVWNfJlU1WBBXfe5XgHuW6BVvHN2ocy_SmnpYp4fZTkde4b8PD6Z3xTAFBGUZQjefnBPEfndBGTEHH8cJunucIBnK9ZtmnajMAzq5yWNqKgvWUT4uJnhNvJ3bAPtaUS0U7T1WxECd1UlfdB0ETBtS3LXuugAWkINZ-AAKk8YtGzLTNuGz3PI4sdsPcHvW_ZgEOVrENbT_MUvSE4VUIHQGtM-Pt2Zs1X_3HznDMQsdVBFAtB4fQhgVbqx0JAsA44cgMEYLEAYiQcC4FIMQZwJAKDUFoJg9yjAmAEMaBAgwYBSCfD8FdJBog-hxASEMLAawMFYKIGQKgNBKDYAIf9YhWDSFwMod4Pw2B-D0GQfQ1BTD0EEPYbgrhPCsF8JIWoMhhhhHIDaJvWhKDThoLwHInBnD8HKKIao4oQA&amp;debug=false&amp;forceAllTransforms=false&amp;modules=false&amp;shippedProposals=false&amp;circleciRepo=&amp;evaluate=true&amp;fileSize=false&amp;timeTravel=false&amp;sourceType=module&amp;lineWrap=true&amp;presets=stage-3&amp;prettier=false&amp;targets=Node-10.1&amp;version=7.23.2&amp;externalPlugins=&amp;assumptions=%7B%7D\" rel=\"noopener noreferrer nofollow\">\u043d\u0430 \u043e\u043d\u043b\u0430\u0439\u043d \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441 \u043a\u043e\u0434\u043e\u043c \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430<\/a>. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u0414\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435, \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/010\/c62\/a38\/010c62a386546a91bde25c14069e9ed8.png\" alt=\"\u041e\u043a\u043d\u043e \u043a\u043e\u0434\u0430, \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u043b\u0435\u0440\u0430 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u0438\" title=\"\u041e\u043a\u043d\u043e \u043a\u043e\u0434\u0430, \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u043b\u0435\u0440\u0430 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u0438\" width=\"1920\" height=\"319\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/010\/c62\/a38\/010c62a386546a91bde25c14069e9ed8.png\"\/><\/p>\n<div><figcaption>\u041e\u043a\u043d\u043e \u043a\u043e\u0434\u0430, \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u043b\u0435\u0440\u0430 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u0438<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/773092\/\"> https:\/\/habr.com\/ru\/articles\/773092\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u043a Yandex Cup 2023<\/figcaption><\/div>\n<\/figure>\n<p>\u0423\u0447\u0430\u0441\u0442\u0438\u0435 \u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u0434\u0430\u0435\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u043f\u0438\u043d\u043e\u043a \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0442\u043e, \u0447\u0442\u043e \u0435\u0449\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0438\u0440\u0435 JS \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e. \u0412\u043e\u0442 \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u0432 \u044d\u0442\u043e\u043c \u0433\u043e\u0434\u0443, \u0432\u0441\u0435 \u0436\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0430\u0440\u0443 \u0442\u0440\u043e\u0439\u043a\u0443 \u0437\u0430\u0434\u0430\u0447. \u0418 \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u0440\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u0440\u043e \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0438\u0442\u0447\u0443 \u0432 JS &#8212; \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0439\u0441\u044f \u043a \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c. <\/p>\n<hr\/>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u044f \u0440\u0430\u043d\u0435\u0435 \u0441\u043b\u044b\u0448\u0430\u043b \u043f\u0440\u043e \u0442\u043e, \u0447\u0442\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0430\u0442\u0438\u0432\u043d\u043e, &#171;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&#187;, \u0432 JS. \u0422\u0430\u043a\u0430\u044f \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0442\u0435\u0445\u043d\u0438\u043a\u0430 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0430 \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0432 \u043f\u0438\u0442\u043e\u043d\u0435. \u041d\u0443 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b, \u043f\u043e\u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u0434\u0443 \u0431\u044b\u0442\u044c \u043b\u0443\u0447\u0448\u0435 \u0438 \u0432 \u043f\u043b\u0430\u043d\u0435 \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u0437 TypeScript \u0432 JavaScript.<\/p>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0432 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u043d\u044b\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u0435\u043b \u0432 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u041f\u043e\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e, \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0435\u043c \u0435\u0441\u043b\u0438 \u0431\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0432\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 &#171;\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0438\u0447\u0438&#187; \u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u0418 \u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 B &#8212; &#171;\u0411\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0443\u0437\u044b\u043a\u0430&#187;<\/summary>\n<div class=\"spoiler__content\">\n<h2>B. \u0411\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043c\u0443\u0437\u044b\u043a\u0430 (20 \u0431\u0430\u043b\u043b\u043e\u0432)<\/h2>\n<p>\u041e\u0434\u043d\u0430\u0436\u0434\u044b \u0426\u0430\u043d\u0441 \u0425\u0438\u043c\u043c\u0435\u0440, \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0442\u043e\u0440 XII \u0432\u0435\u043a\u0430, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0430\u0443\u043d\u0434\u0442\u0440\u0435\u043a\u0430\u043c\u0438 \u043a \u0444\u0438\u043b\u044c\u043c\u0430\u043c, \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043f\u0438\u0448\u0435\u0442 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u0443\u044e \u043c\u0443\u0437\u044b\u043a\u0443, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0435\u0451 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043d\u0435\u0432\u0438\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043f\u0435\u0440\u0444\u043e\u0440\u043c\u0430\u043d\u0441 \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0430 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0435 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0426\u0430\u043d\u0441 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0441\u044b\u0433\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0451 \u0443\u0436\u0435 \u0441\u0442\u0430\u0432\u0448\u0435\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 Time \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u043d\u0430 \u043e\u0433\u0440\u043e\u043c\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0442\u0435 \u0437\u0432\u0443\u043a\u0438, \u0447\u0442\u043e \u0438\u0437\u0434\u0430\u0451\u0442 \u0435\u0433\u043e \u0444\u043e\u0440\u0442\u0435\u043f\u0438\u0430\u043d\u043e.<\/p>\n<p>\u0412\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0442\u044b \u0432 \u0446\u0432\u0435\u0442\u0430 \u043f\u0430\u043b\u0438\u0442\u0440\u044b OKLCH, \u0447\u0442\u043e\u0431\u044b \u043c\u0430\u0441\u0442\u0435\u0440 \u0441\u043c\u043e\u0433 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0435.<\/p>\n<h3>\u0423\u0441\u043b\u043e\u0432\u0438\u0435<\/h3>\n<p>\u0426\u0432\u0435\u0442\u0430 \u0432 OKLCH \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: &#171;48% 0.27 274 \/ 1&#187; (L C H \/ a)<\/p>\n<p>\u0412\u0438\u0434\u0438\u043c\u044b\u0435 \u0446\u0432\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430\u0445 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432\u00a0<a href=\"https:\/\/web-standards.ru\/articles\/oklch-in-css-why-quit-rgb-hsl\/#section-1\" rel=\"noopener noreferrer nofollow\">https:\/\/web-standards.ru\/articles\/oklch-in-css-why-quit-rgb-hsl\/#section-1<\/a>):<\/p>\n<ul>\n<li>\n<p>L \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 100% (\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430\u0445)<\/p>\n<\/li>\n<li>\n<p>C \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 0.37<\/p>\n<\/li>\n<li>\n<p>H \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 360<\/p>\n<\/li>\n<li>\n<p>a \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 0 \u0434\u043e 1<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b @Color \u0438 @ColorPlayer, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0436\u0443\u0442 \u0438\u0433\u0440\u0443 \u043d\u043e\u0442 \u0441 \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 @Color:<\/p>\n<p>@Color(&#171;L&#187;, &#171;10%&#187;) playA(octave)<\/p>\n<p>@Color(&#171;\u0421&#187;, &#171;0.11&#187;) playB(octave)<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 playA (\u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u044b\u043c) \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043a\u0442\u0430\u0432\u043e\u0439 octave (\u043e\u0442 0 \u0434\u043e 8), \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 L \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u043d\u0430 L + (octave &#8212; 3) * 10 (\u0442\u0430\u043a \u043a\u0430\u043a L \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430\u0445).<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 playB \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043a\u0442\u0430\u0432\u043e\u0439 octave (\u043e\u0442 0 \u0434\u043e 8), \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 C \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u043d\u0430 C + (octave &#8212; 3) * 0.11.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422.\u0435. \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u0438\u043c\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0437\u0430\u0434\u0430\u0435\u0442 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u043a\u0442\u0430\u0432\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u043e\u043a\u0442\u0430\u0432\u044b (\u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439). \u0412\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435. \u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0435\u0435\u0441\u044f \u0447\u0438\u0441\u043b\u043e \u043e\u043a\u0440\u0443\u0433\u043b\u044f\u0435\u043c \u0434\u043e \u0434\u0432\u0443\u0445 \u0437\u043d\u0430\u043a\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f .toFixed(2).<\/p>\n<p>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 @ColorPlayer \u0437\u0430\u0434\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043a\u043e\u043b\u0431\u044d\u043a, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 (\u0432\u044b\u0437\u043e\u0432 play*) \u0438 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0434 \u0432\u0441\u0435\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c\u0438 \u0441 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code>@ColorPlayer(\"48% 0.27 274 \/ 1\", (color) => console.log(color)) class Piano {     @Color(\"L\", \"10%\")     playA(octave) {} @Color(\"C\", \"0.15\") playB(octave) {}  @Color(\"H\", \"0.03\") playC(octave) {}  @Color(\"L\", \"10%\") playD(octave) {}  @Color(\"C\", \"0.15\") playE(octave) {}  @Color(\"H\", \"0.1\") playF(octave) {}  @Color(\"a\", \"0.4\") playG(octave) {}  } <\/code><\/pre>\n<pre><code>const piano = new Piano(); \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playA(2) \/\/ console.log(\"38.00% 0.27 274.00 \/ 1.00\") piano.playA(4) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") piano.playB(3) \/\/ console.log(\"48.00% 0.27 274.00 \/ 1.00\") <\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438:<\/p>\n<pre><code>export function ColorPlayer(initialColor, cb) { } <\/code><\/pre>\n<pre><code>export function Color(component, coeff) { } <\/code><\/pre>\n<p><em>\u0412\u0430\u0436\u043d\u043e<\/em>: \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e 2023 \u0433\u043e\u0434\u0430\u00a0<a href=\"https:\/\/github.com\/tc39\/proposal-decorators\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/tc39\/proposal-decorators<\/a>\u00a0\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f babel. \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442\u00a0<a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/531664\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/otus\/articles\/531664\/<\/a>, \u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 2023 \u0433\u043e\u0434\u0430 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0432\u044b\u0448\u0435.<\/p>\n<\/div>\n<\/details>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f \u0444\u0438\u0447\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u043e\u0432, &#171;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&#187;, \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0438\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0432 <strong>20<\/strong> \u0438\u0437 <strong>20<\/strong> \u0431\u0430\u043b\u043b\u043e\u0432.<\/p>\n<details class=\"spoiler\">\n<summary>package.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>{   \"name\": \"project\",   \"version\": \"1.0.0\",   \"description\": \"\",   \"main\": \"index.js\",   \"scripts\": {     \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\",     \"build\": \"babel src -d lib\",     \"start\": \"babel src -d lib &amp;&amp; node lib\/index.js\"   },   \"keywords\": [],   \"author\": \"\",   \"license\": \"ISC\",   \"devDependencies\": {     \"@babel\/cli\": \"^7.23.0\",     \"@babel\/core\": \"^7.23.2\",     \"@babel\/plugin-proposal-decorators\": \"^7.23.2\",     \"@babel\/preset-env\": \"^7.23.2\"   } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>babel.config.json<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>{     \"presets\": [         \"@babel\/preset-env\"     ],     \"plugins\": [         [             \"@babel\/plugin-proposal-decorators\",             {                \"version\": \"2023-05\"             }         ]     ] }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0418\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u043c<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430, \u043a\u0430\u043a \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0438\u0436\u0435:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/babeljs.io\/docs\/babel-plugin-proposal-decorators\" rel=\"noopener noreferrer nofollow\">@babel\/plugin-proposal-decorators \u00b7 Babel (babeljs.io)<\/a>.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#classes\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes (github.com)<\/a>  <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#class-fields\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes class-fields (github.com)<\/a>  <\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/tc39\/proposal-decorators#example-customelement\" rel=\"noopener noreferrer nofollow\">tc39\/proposal-decorators: Decorators for ES6 classes customelement (github.com)<\/a>  <\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0446\u0432\u0435\u0442\u0430 \u0432 \u043d\u043e\u0442\u0430\u0446\u0438\u0438 (L C H \/ a)  <\/h3>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0438 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u0434\u0430. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <em>InitialColor<\/em>. \u041d\u043e \u0432 \u0437\u0430\u0434\u0430\u0447\u0435, \u0442\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u0447\u0435\u0441\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0439\u0442\u0438 \u0447\u0438\u0441\u043b\u043e, \u043d\u043e \u043d\u0435 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0437\u044f\u0442\u044c \u043b\u0438\u0431\u043e \u043d\u0438\u0436\u043d\u044e\u044e \u0433\u0440\u0430\u043d\u0438\u0446\u0443, \u043b\u0438\u0431\u043e \u0432\u0435\u0440\u0445\u043d\u044e\u044e, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0443\u0434\u0430 \u0443\u0441\u0442\u0440\u0435\u043c\u0438\u043b\u043e\u0441\u044c \u043d\u043e\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u0412 \u044d\u0442\u043e\u043c \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 <em>\u0433\u0435\u0442\u0442\u0435\u0440\u044b<\/em> \u0438 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u044b<\/em> \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043d\u0438\u0436\u0435, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043a\u043e\u0434 <em>\u0433\u0435\u0442\u0442\u0435\u0440\u0430<\/em> \u0438 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u0430<\/em> \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>L<\/em> \u043a\u043b\u0430\u0441\u0441\u0430 <em>InitialColor:<\/em><\/p>\n<pre><code class=\"javascript\">... get L() {     return this.Lv }  set L(v) {     if (v &lt; 0 || v > 100) {         this.Lv = Math.min(100, Math.max(0, v))     } else {         this.Lv = v     } } ...<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u044e\u043a \u0441 min\/max.<\/p>\n<pre><code class=\"javascript\">Math.min(100 \/* \u0447\u0438\u0441\u043b\u043e_\u0432\u0435\u0440\u0445\u043d\u0435\u0439_\u0433\u0440\u0430\u043d\u0438\u0446\u044b *\/, Math.max(0 \/* \u0447\u0438\u0441\u043b\u043e_\u043d\u0438\u0436\u043d\u0435\u0439_\u0433\u0440\u0430\u043d\u0438\u0446\u044b *\/, v))<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043d\u0443\u0436\u043d\u043e \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430, \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. <\/p>\n<pre><code class=\"javascript\">class InitialColor {     constructor(value) {         const [Lv, Cv, Hv, ,av] = value.split(' ')         this.Lv = parseFloat(Lv)         this.Cv = parseFloat(Cv)         this.Hv = parseFloat(Hv)         this.av = parseFloat(av)     }        ... }<\/code><\/pre>\n<p>\u0418 \u0435\u0449\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e, \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>toString()<\/code>.<\/p>\n<pre><code class=\"javascript\">class InitialColor {     \/\/ ...     toString() {         return `${this.L.toFixed(2)}% ${this.C.toFixed(2)} ${this.H.toFixed(2)} \/ ${this.a.toFixed(2)}`     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 ColorPlayer <\/h3>\n<p>\u0414\u043b\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430 <em>Color<\/em>, \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0432\u0435\u0442\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 <em>ColorPlayer<\/em>. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u0432 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u0440\u044e\u043a, \u043c\u043e\u0436\u043d\u043e \u043b\u0438\u0448\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0442 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u043c \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043d\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439, \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u0431\u0435\u0437 \u0432\u0440\u0435\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430 <em>ColorPlayer<\/em>:<\/p>\n<pre><code class=\"javascript\">export function ColorPlayer(initialColor \/*\u0446\u0432\u0435\u0442*\/, cb \/*\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f*\/) {     \/\/ ...     return function decorator(target, { kind, addInitializer }) {         if (kind === 'class') {             \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442 target             return class extends target {                 cb = cb \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441 \u043a\u043e\u043b\u0431\u0435\u043a\u043e\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f                 initialColor = new InitialColor(initialColor) \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0446\u0432\u0435\u0442\u0430                 constructor() {                     super(...arguments)                     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e)                     cb(new InitialColor(initialColor).toString())                 }             }         }     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <code>cb<\/code>  \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <em>initialColor<\/em> (\u0434\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0438 \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u043e\u043a\u0440\u0430\u0442\u043d\u043e, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043a\u043b\u0430\u0441\u0441\u0430):<\/p>\n<pre><code class=\"javascript\">cb(new InitialColor(initialColor).toString())<\/code><\/pre>\n<h3>\u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 Color<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0435, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043d\u0430\u0434 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 <em>initialColor<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0443 <em>ColorPlayer, <\/em>\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u043a\u043e\u0434 \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"javascript\">export function Color(component, coeff) {     return function (fn, { kind }) {         if (kind === 'method') {             return function (octave) {                 this.initialColor[component] += ((parseFloat(octave) - 3) * parseFloat(coeff))                 this.cb(this.initialColor.toString())                 fn.call(this, octave)             }         }         return fn     } }<\/code><\/pre>\n<p>\u041f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e, \u0432 \u0437\u0430\u0434\u0430\u0447\u0435 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u043a\u0442\u0430\u0432\u044b \u043d\u0430 3 \u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442. \u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 InitialColor \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 <em>\u0441\u0435\u0442\u0442\u0435\u0440\u044b<\/em>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u044b \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b, \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0441\u0435\u0431\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443, \u043a\u0430\u043a \u043d\u0438\u0436\u0435:<\/p>\n<pre><code>this.initialColor[component] += ((parseFloat(octave) - 3) * parseFloat(coeff))<\/code><\/pre>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435, \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>initialColor<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>cb<\/code> , \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u0442\u044c, \u0441\u0430\u043c\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u0447\u0435\u0440\u0435\u0437 <code>fn.call(this,<\/code><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-359817","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/359817","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=359817"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/359817\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=359817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=359817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=359817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}