{"id":500807,"date":"2026-10-29T11:29:46","date_gmt":"2026-10-29T08:29:46","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=500807"},"modified":"2026-10-29T11:29:46","modified_gmt":"2026-10-29T08:29:46","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=500807","title":{"rendered":"\u041a\u0430\u043a \u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043b NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0438 Telegram \u0432 60 fps, \u043d\u0435 \u0438\u043c\u0435\u044f API: \u0431\u043e\u0442 \u0434\u043b\u044f \u044d\u043c\u043e\u0434\u0437\u0438, \u0441\u0442\u0438\u043a\u0435\u0440\u043e\u0432 \u0438 \u043f\u043e\u0434\u0430\u0440\u043a\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\/extt\/a4\/79\/04\/a47904abfa46d564420f7d25eddbf9d3.webp\" alt=\"Resistance Dog #14 072 \u2014 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0438\u0441\u0443\u0435\u0442 \u0431\u043e\u0442\" width=\"1229\" height=\"811\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/a4\/79\/04\/a47904abfa46d564420f7d25eddbf9d3.webp 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/a4\/79\/04\/a47904abfa46d564420f7d25eddbf9d3.webp 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Resistance Dog #14 072 \u2014 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0438\u0441\u0443\u0435\u0442 \u0431\u043e\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 Telegram \u0435\u0441\u0442\u044c \u043f\u0440\u0435\u043c\u0438\u0443\u043c-\u044d\u043c\u043e\u0434\u0437\u0438, \u043f\u0430\u043a\u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u043e\u0432 \u0438 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0438. \u0412\u0441\u0451 \u044d\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043e\u0442\u0442\u0443\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043f\u0430\u043a \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043d\u0435\u043b\u044c\u0437\u044f. \u0427\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c\u00a0<code>custom_emoji_id<\/code>, \u043d\u0443\u0436\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043e\u0442 \u0438\u043b\u0438 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a. \u0410 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u043d\u0435 Telegram \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u044d\u043a\u0440\u0430\u043d\u0430.<\/p>\n<p>\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0431\u043e\u0442\u0430\u00a0<strong>Emoji Studio<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u2014 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e \u0441\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u043e \u0434\u043e\u0440\u043e\u0433\u0435:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043f\u043e\u0434\u0430\u0440\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u0443 Telegram \u043d\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e API;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043a\u0430\u0434\u0440\u043e\u0432 Lottie \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0451\u043c\u043d\u0430\u044f \u043e\u0431\u0432\u043e\u0434\u043a\u0430 \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u0437\u044f\u043b\u0441\u044f \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0439 \u043a\u0432\u0430\u0434\u0440\u0430\u0442;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u043f\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u043b\u0438 \u0442\u0435\u043d\u0438 \u0438 \u0431\u043b\u0438\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0442\u0435\u043a: Python 3.12, aiogram 3, rlottie-python, numpy, Pillow, ffmpeg, SQLite. \u041a\u043e\u0434 \u043e\u0442\u043a\u0440\u044b\u0442:\u00a0<a href=\"http:\/\/github.com\/alvaro-lox\/emoji-studio-bot\" rel=\"noopener nofollow\">github.com\/alvaro-lox\/emoji-studio-bot<\/a>.<\/p>\n<h3>\u0427\u0442\u043e \u0443\u043c\u0435\u0435\u0442 \u0431\u043e\u0442<\/h3>\n<p>\u041c\u0435\u043d\u044e \u0440\u0430\u0437\u0431\u0438\u0442\u043e \u043d\u0430 \u0434\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430.<\/p>\n<p><strong>\ud83e\udde9 \u042d\u043c\u043e\u0434\u0437\u0438 \u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u044b.<\/strong>\u00a0\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c, \u0438 \u0431\u043e\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0451, \u0447\u0442\u043e \u0435\u043c\u0443 \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u044e\u0442:<\/p>\n<ul>\n<li>\n<p><strong>ID \u044d\u043c\u043e\u0434\u0437\u0438<\/strong>\u00a0\u2014\u00a0<code>custom_emoji_id<\/code>\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043c\u043e\u0434\u0437\u0438, \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u00bb \u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f python-telegram-bot, aiogram, Telethon \u0438 Pyrogram. \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0433\u043e \u043f\u0430\u043a\u0430 \u2014 \u0441\u043f\u0438\u0441\u043e\u043a ID \u0438 JSON-\u0444\u0430\u0439\u043b.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043a\u0430\u0447\u0430\u0442\u044c<\/strong>\u00a0\u2014 \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u0440\u0438\u0441\u043b\u0430\u043d\u043e \u043f\u043e\u0434\u0440\u044f\u0434, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043e\u0434\u043d\u0438\u043c zip (<code>.tgs<\/code>,\u00a0<code>.webm<\/code>,\u00a0<code>.webp<\/code>).<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c<\/strong>\u00a0\u2014 \u043f\u0430\u043a \u0432 \u043b\u044e\u0431\u043e\u0439 \u0446\u0432\u0435\u0442, \u0441 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0432 Telegram\u00bb.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0430\u043a \u0434\u0430\u0451\u0442 \u043f\u0440\u0435\u0432\u044c\u044e \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u043a\u0430 \u043e\u0434\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u043e\u0439, \u0430 \u0444\u043e\u0442\u043e, GIF \u0438\u043b\u0438 \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u044d\u043c\u043e\u0434\u0437\u0438 100\u00d7100.<\/p>\n<p><strong>\ud83c\udf81 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0438.<\/strong>\u00a0\u041f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0448\u044c\u00a0<a href=\"https:\/\/t.me\/nft\/plushpepe-1\" rel=\"noopener nofollow\"><code>https:\/\/t.me\/nft\/plushpepe-1<\/code><\/a>\u00a0\u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0448\u044c MP4 \u0432 60 fps, \u043a\u0430\u043a \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u0432 Telegram. \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 (3:2, 1:1 \u0434\u043b\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0438, 9:16 \u0434\u043b\u044f \u0441\u0442\u043e\u0440\u0438\u0441), \u0441\u0432\u043e\u0439 \u0444\u043e\u043d, \u0441\u0432\u043e\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u044c, \u0441\u043a\u0430\u0447\u0430\u0442\u044c GIF \u0438\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c\u00a0<code>.tgs<\/code>. \u041c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0436\u043a\u0443: \u0431\u043e\u0442 \u043d\u0430\u043f\u0438\u0448\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0441\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/extt\/1f\/40\/4b\/1f404b61dc0b39fb1f1a631fa5ec005c.png\" alt=\"\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e: \u0434\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\" width=\"472\" height=\"329\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/1f\/40\/4b\/1f404b61dc0b39fb1f1a631fa5ec005c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/1f\/40\/4b\/1f404b61dc0b39fb1f1a631fa5ec005c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e: \u0434\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/extt\/0b\/72\/4a\/0b724ab60685fe3bff91bc71ce96a66c.png\" alt=\"\u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u044d\u043c\u043e\u0434\u0437\u0438: ID, \u043a\u043e\u0434, \u0432\u0441\u0435 ID \u043f\u0430\u043a\u0430, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430\" width=\"374\" height=\"395\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/0b\/72\/4a\/0b724ab60685fe3bff91bc71ce96a66c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/0b\/72\/4a\/0b724ab60685fe3bff91bc71ce96a66c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u044d\u043c\u043e\u0434\u0437\u0438: ID, \u043a\u043e\u0434, \u0432\u0441\u0435 ID \u043f\u0430\u043a\u0430, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 1. \u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0430\u0440\u043e\u043a \u0431\u0435\u0437 API<\/h3>\n<p>\u0412 Bot API \u043d\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u0430 \u00ab\u043e\u0442\u0434\u0430\u0439 \u043c\u043d\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0430\u00bb. \u0417\u0430\u0442\u043e \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u00a0<a href=\"http:\/\/t.me\/nft\/&lt;slug&gt;\" rel=\"noopener nofollow\"><code>t.me\/nft\/&lt;slug&gt;<\/code><\/a>, \u0438 Telegram \u0441\u0430\u043c \u0440\u0438\u0441\u0443\u0435\u0442 \u043d\u0430 \u043d\u0435\u0439 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u0415\u0441\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435:<\/p>\n<ul>\n<li>\n<p>\u0440\u0430\u0434\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u0444\u043e\u043d\u0430 \u2014 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 SVG \u0441\u00a0<code>&lt;stop stop-color=\"\u2026\"&gt;<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0443\u0437\u043e\u0440 \u2014 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430-\u043f\u043b\u0438\u0442\u043a\u0430\u00a0<code>#giftPattern<\/code>\u00a0\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0435\u0451 \u043a\u043e\u043f\u0438\u0439 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043e\u043c \u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c\u044e;<\/p>\n<\/li>\n<li>\n<p>\u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<code>.tgs<\/code>\u00a0\u0432\u00a0<code>&lt;source type=\"application\/x-tgsticker\"&gt;<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043c\u043e\u0434\u0435\u043b\u044c\u044e, \u0444\u043e\u043d\u043e\u043c, \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c, \u0438\u0445 \u0440\u0435\u0434\u043a\u043e\u0441\u0442\u044c\u044e \u0438 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0420\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0443 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a:<\/p>\n<pre><code>for opacity, x, y, scale in re.findall(    r'&lt;g opacity=\"([\\d.]+)\" transform=\"translate\\(([-\\d.]+),\\s*([-\\d.]+)\\)\"&gt;\\s*'    r'&lt;use xlink:href=\"#giftPattern\" transform=\"scale\\(([\\d.]+)\\)\"',    html,):    info.pattern.append(PatternItem(float(x), float(y), float(scale), float(opacity)))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper\"><\/span><\/a><\/div><\/pre>\n<p><code>    r'&lt;g opacity=\"([\\d.]+)\" transform=\"translate\\(([-\\d.]+),\\s*([-\\d.]+)\\)\"&gt;\\s*'<\/code><\/p>\n<p><code>    r'&lt;use xlink:href=\"#giftPattern\" transform=\"scale\\(([\\d.]+)\\)\"',<\/code><\/p>\n<p><code>    html,<\/code><\/p>\n<p><code>):<\/code><\/p>\n<p><code>    info.pattern.append(PatternItem(float(x), float(y), float(scale), float(opacity)))<\/code><\/p>\n<p>\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0443\u0437\u043e\u0440\u0430 \u0437\u0430\u0434\u0430\u043d\u044b \u0434\u043b\u044f \u0445\u043e\u043b\u0441\u0442\u0430 420\u00d7280, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u043b\u044c\u0448\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u044e \u0438\u0445 \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440. \u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 9:16 \u0445\u043e\u043b\u0441\u0442 \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0432\u044b\u0441\u043e\u0442\u0435, \u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0443\u0437\u043e\u0440 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443.<\/p>\n<p>\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u043e HTML-\u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u2014 \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440. \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f, \u043d\u0443\u0436\u043d\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b, \u0430 \u0435\u0441\u043b\u0438 Telegram \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u0451\u0440\u0441\u0442\u043a\u0443, \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0437\u0431\u043e\u0440\u0430. \u0417\u0430\u0442\u043e \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0435\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u044f\u0445 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 2. \u0422\u0451\u043c\u043d\u0430\u044f \u043e\u0431\u0432\u043e\u0434\u043a\u0430, \u0438\u043b\u0438 premultiplied alpha<\/h3>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u2014 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f Lottie. \u041a\u0430\u0434\u0440\u044b \u044f \u043f\u043e\u043b\u0443\u0447\u0430\u044e \u0447\u0435\u0440\u0435\u0437 rlottie (\u0442\u043e\u0442 \u0436\u0435 \u0434\u0432\u0438\u0436\u043e\u043a, \u0447\u0442\u043e \u0438 \u0432 \u0441\u0430\u043c\u043e\u043c Telegram) \u0438 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e \u043d\u0430 \u0444\u043e\u043d \u0432 numpy. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u0435\u043b\u0430\u043b\u0430 \u044d\u0442\u043e \u043f\u043e \u0443\u0447\u0435\u0431\u043d\u0438\u043a\u0443:<\/p>\n<pre><code>out = src * a + dst * (1 - a)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0418 \u043f\u043e \u043a\u0440\u0430\u044f\u043c \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0433\u0440\u044f\u0437\u043d\u0430\u044f \u0442\u0451\u043c\u043d\u0430\u044f \u043a\u0430\u0439\u043c\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e rlottie \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u0441\u00a0<strong>premultiplied alpha<\/strong>: \u0446\u0432\u0435\u0442 \u0443\u0436\u0435 \u0443\u043c\u043d\u043e\u0436\u0435\u043d \u043d\u0430 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u0443\u043c\u043d\u043e\u0436\u0438\u0442\u044c \u0435\u0433\u043e \u0435\u0449\u0451 \u0440\u0430\u0437, \u043f\u043e\u043b\u0443\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u043d\u0430 \u043a\u0440\u0430\u044f\u0445 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0442\u0435\u043c\u043d\u0435\u0435, \u0447\u0435\u043c \u0434\u043e\u043b\u0436\u043d\u044b. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0430 \u043a\u043e\u0440\u043e\u0447\u0435:<\/p>\n<pre><code># rlottie \u043e\u0442\u0434\u0430\u0451\u0442 premultiplied alpha: out = src + dst * (1 - a)alpha = model[..., 3:4] \/ 255.0composed = np.clip(model[..., :3] + region * (1 - alpha), 0, 255).astype(np.uint8)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>alpha = model[..., 3:4] \/ 255.0<\/code><\/p>\n<p><code>composed = np.clip(model[..., :3] + region * (1 - alpha), 0, 255).astype(np.uint8)<\/code><\/p>\n<p>\u0422\u0430 \u0436\u0435 \u043b\u043e\u0432\u0443\u0448\u043a\u0430 \u0435\u0441\u0442\u044c \u0432 Pillow: \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043a\u0430\u0434\u0440\u0430 rlottie \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043a\u0430\u043a\u00a0<code>RGBA<\/code>, \u043a\u0440\u0430\u044f \u0431\u0443\u0434\u0443\u0442 \u0442\u0451\u043c\u043d\u044b\u043c\u0438. \u041d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a\u00a0<code>RGBa<\/code>\u00a0(\u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u00aba\u00bb \u2014 \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c premultiplied), \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 3. 60 fps \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432<\/h3>\n<p>\u0423 Lottie \u0441\u0432\u043e\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u043e\u0432, \u043e\u0431\u044b\u0447\u043d\u043e 30 \u0438\u043b\u0438 60. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u043e\u0432\u043d\u043e 60 fps, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u044f \u0431\u0435\u0440\u0443 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0435\u0433\u043e \u043d\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u044e:<\/p>\n<pre><code>for k in range(frames_out):    index = min(total - 1, int(k * rate \/ FPS))    if index != last_index:        ...  # \u0440\u0435\u043d\u0434\u0435\u0440 \u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435    bg[vy0:vy1, vx0:vx1] = composed    stdin.write(bg.tobytes())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>    index = min(total - 1, int(k * rate \/ FPS))<\/code><\/p>\n<p><code>    if index != last_index:<\/code><\/p>\n<p><code>        ...  # \u0440\u0435\u043d\u0434\u0435\u0440 \u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/code><\/p>\n<p><code>    bg[vy0:vy1, vx0:vx1] = composed<\/code><\/p>\n<p><code>    stdin.write(bg.tobytes())<\/code><\/p>\n<p>\u041a\u0430\u0434\u0440\u044b \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0434\u0438\u0441\u043a: \u0441\u044b\u0440\u044b\u0435 RGB-\u0431\u0430\u0439\u0442\u044b \u0438\u0434\u0443\u0442 \u0441\u0440\u0430\u0437\u0443 \u0432 ffmpeg \u0447\u0435\u0440\u0435\u0437 pipe (<code>-f rawvideo -pix_fmt rgb24 -i -<\/code>), \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 libx264 \u0441\u00a0<code>crf 18<\/code>\u00a0\u0438\u00a0<code>+faststart<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e \u0438\u0433\u0440\u0430\u0442\u044c \u0434\u043e \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0424\u043e\u043d \u0441 \u0443\u0437\u043e\u0440\u043e\u043c \u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u0430\u0434\u0440\u0435 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u043f\u043e\u0434 \u043c\u043e\u0434\u0435\u043b\u044c\u044e.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043c\u0435\u043b\u043e\u0447\u044c \u2014 GIF. \u0412 \u043d\u0451\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u0430\u0434\u0440\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u0442\u044b\u0445 \u0434\u043e\u043b\u044f\u0445 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 60 fps \u0442\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e: 1\/60 \u0441 \u043e\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u0441\u044f \u0434\u043e 0,02 \u0441, \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u0434\u043b\u0438\u0442\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 GIF \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 50 fps, \u0441 \u043f\u0430\u043b\u0438\u0442\u0440\u043e\u0439 \u0447\u0435\u0440\u0435\u0437\u00a0<code>palettegen<\/code>\/<code>paletteuse<\/code>, \u0447\u0442\u043e\u0431\u044b \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u043d\u0435 \u0448\u0451\u043b \u043f\u043e\u043b\u043e\u0441\u0430\u043c\u0438.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 4. \u041a\u0432\u0430\u0434\u0440\u0430\u0442 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u043e\u0434\u0430\u0440\u043a\u0430<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0431\u0430\u0433. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442: \u0432\u043e\u043a\u0440\u0443\u0433 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u0438\u0434\u0435\u043d \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0439 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0444\u043e\u043d\u043e\u043c.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/extt\/35\/ee\/08\/35ee08c09d8e817ed19237639c6b8b3e.png\" alt=\"\u0422\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043a\u0432\u0430\u0434\u0440\u0430\u0442: \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 Fragment \u043f\u043e\u0432\u0435\u0440\u0445 \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u043e\u043d\u0430\" width=\"1231\" height=\"830\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/extt\/35\/ee\/08\/35ee08c09d8e817ed19237639c6b8b3e.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/extt\/35\/ee\/08\/35ee08c09d8e817ed19237639c6b8b3e.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>\u0422\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043a\u0432\u0430\u0434\u0440\u0430\u0442: \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 Fragment \u043f\u043e\u0432\u0435\u0440\u0445 \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u043e\u043d\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435. \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e\u0434\u0440\u044f\u0434,\u00a0<a href=\"http:\/\/t.me\/nft\/%E2%80%A6\" rel=\"noopener nofollow\"><code>t.me\/nft\/\u2026<\/code><\/a>\u00a0\u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u0430\u0440\u043a\u0430. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0442\u043e\u0436\u0435 \u0436\u0438\u0432\u0451\u0442 \u043d\u0435\u0434\u043e\u043b\u0433\u043e. \u041d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0443 \u0431\u043e\u0442\u0430 \u0431\u044b\u043b \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u0443\u0442\u044c:\u00a0<a href=\"http:\/\/nft.fragment.com\/gift\/&lt;slug&gt;.tgs\" rel=\"noopener nofollow\"><code>nft.fragment.com\/gift\/&lt;slug&gt;.tgs<\/code><\/a>.<\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Fragment \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u043e\u0442\u0434\u0430\u0451\u0442\u00a0<strong>\u043d\u0435 \u043c\u043e\u0434\u0435\u043b\u044c, \u0430 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443<\/strong>: \u0444\u043e\u043d, \u0443\u0437\u043e\u0440 \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0432 \u043e\u0434\u043d\u043e\u043c Lottie-\u0444\u0430\u0439\u043b\u0435. \u0411\u043e\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u043b \u044d\u0442\u0443 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u043f\u043e\u0432\u0435\u0440\u0445 \u0441\u0432\u043e\u0435\u0433\u043e \u0444\u043e\u043d\u0430, \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0441\u044f \u043a\u0432\u0430\u0434\u0440\u0430\u0442. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e: \u0432 \u0443\u0433\u043b\u0430\u0445 \u043a\u0430\u0434\u0440\u0430 \u0438\u0437 Fragment \u0430\u043b\u044c\u0444\u0430 \u043e\u043a\u043e\u043b\u043e 251, \u0430 \u0443 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u2014 0.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u044c, \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 Fragment \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e: \u0441\u043b\u043e\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f\u00a0<code>Background<\/code>,\u00a0<code>Pattern<\/code>,\u00a0<code>Color Icon<\/code>, \u0430 \u0441\u0430\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043b\u0435\u0436\u0438\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0430\u0441\u0441\u0435\u0442\u043e\u043c \u0441 id\u00a0<code>G<\/code>. \u0417\u043d\u0430\u0447\u0438\u0442, \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0440\u0435\u0437\u0430\u0442\u044c:<\/p>\n<pre><code>def extract_fragment_model(tgs: bytes) -&gt; bytes:    \"\"\"Fragment \u043e\u0442\u0434\u0430\u0451\u0442 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0430\u0441\u0441\u0435\u0442 G.\"\"\"    data = json.loads(gzip.decompress(tgs))    assets = {a.get(\"id\"): a for a in data.get(\"assets\", [])}    model = assets.get(\"G\")    if not model or not model.get(\"layers\"):        raise ValueError(\"no model asset in fragment tgs\")  # \u043b\u0443\u0447\u0448\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0447\u0435\u043c \u043a\u0432\u0430\u0434\u0440\u0430\u0442    data[\"layers\"] = model[\"layers\"]    data[\"assets\"] = [a for a in data[\"assets\"] if a.get(\"id\") != \"G\"]    return gzip.compress(json.dumps(data, separators=(\",\", \":\")).encode())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>    \"\"\"Fragment \u043e\u0442\u0434\u0430\u0451\u0442 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0430\u0441\u0441\u0435\u0442 G.\"\"\"<\/code><\/p>\n<p><code>    data = json.loads(gzip.decompress(tgs))<\/code><\/p>\n<p><code>    assets = {a.get(\"id\"): a for a in data.get(\"assets\", [])}<\/code><\/p>\n<p><code>    model = assets.get(\"G\")<\/code><\/p>\n<p><code>    if not model or not model.get(\"layers\"):<\/code><\/p>\n<p><code>        raise ValueError(\"no model asset in fragment tgs\")  # \u043b\u0443\u0447\u0448\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0447\u0435\u043c \u043a\u0432\u0430\u0434\u0440\u0430\u0442<\/code><\/p>\n<p><code>    data[\"layers\"] = model[\"layers\"]<\/code><\/p>\n<p><code>    data[\"assets\"] = [a for a in data[\"assets\"] if a.get(\"id\") != \"G\"]<\/code><\/p>\n<p><code>    return gzip.compress(json.dumps(data, separators=(\",\", \":\")).encode())<\/code><\/p>\n<p>\u0418\u0437 \u0442\u043e\u0439 \u0436\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0446\u0432\u0435\u0442\u0430 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 (\u0441\u043b\u043e\u0439\u00a0<code>Background<\/code>) \u0438 \u0443\u0437\u043e\u0440 (\u0441\u043b\u043e\u0439\u00a0<code>Pattern<\/code>). \u0422\u0430\u043a \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 <a href=\"http:\/\/t.me\" rel=\"noopener nofollow\">t.me<\/a> \u043d\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442, \u0431\u043e\u0442 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0440\u0438\u0441\u0443\u0435\u0442 \u043f\u043e\u0434\u0430\u0440\u043e\u043a \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c\u0438 \u0446\u0432\u0435\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0442\u0430\u043a\u0430\u044f: \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 <a href=\"http:\/\/t.me\" rel=\"noopener nofollow\">t.me<\/a>, \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0434\u0432\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u0430 \u0441 \u043f\u0430\u0443\u0437\u043e\u0439, \u043f\u043e\u0442\u043e\u043c Fragment. \u00ab\u041f\u043e\u0434\u0430\u0440\u043e\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u00bb \u0431\u043e\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u043d\u0435\u0442 \u0438 \u0442\u0430\u043c. \u0423 \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0435\u0441\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f: \u043d\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0438 \u0440\u0435\u0434\u043a\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u043d\u0430 10 \u043c\u0438\u043d\u0443\u0442, \u0430 \u0441\u043b\u0435\u0436\u043a\u0430 \u0437\u0430 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c \u0438\u0445 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442, \u0438\u043d\u0430\u0447\u0435 \u0431\u043e\u0442 \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0431\u044b \u043b\u043e\u0436\u043d\u043e\u0435 \u00ab\u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0441\u043c\u0435\u043d\u0438\u043b\u0441\u044f\u00bb.<\/p>\n<p>\u0422\u0435\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0435\u0440\u0435\u0436\u0451\u0442 \u044d\u0442\u043e\u0442 \u0431\u0430\u0433, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0449\u044c: \u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c, \u0443\u0433\u043b\u044b \u043a\u0430\u0434\u0440\u0430 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435.<\/p>\n<h3>\u0417\u0430\u0434\u0430\u0447\u0430 5. \u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430 \u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u0438 \u043e\u0431\u044a\u0451\u043c\u0430<\/h3>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u043f\u0430\u043a \u044d\u043c\u043e\u0434\u0437\u0438 \u0432 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0446\u0432\u0435\u0442\u0430 \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0437\u0430\u043b\u0438\u0432\u043a\u0430: \u0442\u0435\u043d\u0435\u0439 \u0438 \u0431\u043b\u0438\u043a\u043e\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430 \u0438\u0434\u0451\u0442 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 HLS. \u041e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0442\u043e\u043d \u0438 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0430\u00a0<strong>\u0441\u0432\u0435\u0442\u043b\u043e\u0442\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f<\/strong>. \u0422\u0435\u043d\u0438 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u0451\u043c\u043d\u044b\u043c\u0438, \u0431\u043b\u0438\u043a\u0438 \u0441\u0432\u0435\u0442\u043b\u044b\u043c\u0438:<\/p>\n<pre><code>class Tint:    def __init__(self, hex_color: str):        r, g, b = hex_to_rgb(hex_color)        self.hue, self.light, self.sat = colorsys.rgb_to_hls(r, g, b)    def __call__(self, r: float, g: float, b: float) -&gt; tuple[float, float, float]:        _, light, sat = colorsys.rgb_to_hls(r, g, b)        # \u0441\u0435\u0440\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u0442\u043e\u0436\u0435 \u043e\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c, \u043d\u043e \u0447\u0443\u0442\u044c \u0441\u043b\u0430\u0431\u0435\u0435 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445        new_sat = self.sat * (0.55 + 0.45 * sat)        return colorsys.hls_to_rgb(self.hue, light, new_sat)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>    def <strong>init<\/strong>(self, hex_color: str):<\/code><\/p>\n<p><code>        r, g, b = hex_to_rgb(hex_color)<\/code><\/p>\n<p><code>        self.hue, self.light, self.sat = colorsys.rgb_to_hls(r, g, b)<\/code><\/p>\n<p><code>    def <strong>call<\/strong>(self, r: float, g: float, b: float) -&gt; tuple[float, float, float]:<\/code><\/p>\n<p><code>        <em>, light, sat = colorsys.rgb<\/em>to_hls(r, g, b)<\/code><\/p>\n<p><code>        # \u0441\u0435\u0440\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u0442\u043e\u0436\u0435 \u043e\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c, \u043d\u043e \u0447\u0443\u0442\u044c \u0441\u043b\u0430\u0431\u0435\u0435 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445<\/code><\/p>\n<p><code>        new_sat = self.sat <em> (0.55 + 0.45 <\/em> sat)<\/code><\/p>\n<p><code>        return colorsys.hls_to_rgb(self.hue, light, new_sat)<\/code><\/p>\n<p>\u0414\u043b\u044f\u00a0<code>.tgs<\/code>\u00a0\u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0446\u0432\u0435\u0442\u0443 \u0432 JSON Lottie: \u0437\u0430\u043b\u0438\u0432\u043a\u0430\u043c, \u043e\u0431\u0432\u043e\u0434\u043a\u0430\u043c, \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430\u043c (\u0443 \u043d\u0438\u0445 \u0446\u0432\u0435\u0442\u0430 \u043b\u0435\u0436\u0430\u0442 \u043f\u043b\u043e\u0441\u043a\u0438\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0432\u043f\u0435\u0440\u0435\u043c\u0435\u0448\u043a\u0443 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c\u0438) \u0438 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u043a\u0430\u0434\u0440\u0430\u043c. \u0414\u043b\u044f\u00a0<code>.webp<\/code>\u00a0\u2014 \u043f\u043e\u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u043e. \u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0448\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440: \u0431\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437\u00a0<code>createNewStickerSet<\/code>\u00a0\u0438 \u0434\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0435\u0440\u0435\u0437\u00a0<code>addStickerToSet<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 50 \u0441\u0442\u0438\u043a\u0435\u0440\u043e\u0432.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0414\u043e<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043e\u0441\u043b\u0435 (\u0441\u0435\u0440\u044b\u0439)<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"258\" width=\"258\">\n<p align=\"left\">\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"166\" width=\"166\">\n<p align=\"left\">\n<\/td>\n<td>\n<p align=\"left\">\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>\u0422\u0435\u043d\u0438 \u043d\u0430 \u0448\u0432\u0430\u0445, \u0431\u043b\u0438\u043a\u0438 \u043d\u0430 \u043f\u0443\u0433\u043e\u0432\u0438\u0446\u0430\u0445 \u0438 \u043e\u0431\u044a\u0451\u043c \u0441\u0435\u0440\u0434\u0446\u0430 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u2014 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0432\u0435\u0442.<\/p>\n<h3>\u0415\u0449\u0451 \u043f\u0430\u0440\u0430 \u043d\u0435\u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u043c\u0435\u0441\u0442<\/h3>\n<ul>\n<li>\n<p><strong>\u041a\u043e\u0434 \u0434\u043b\u044f Telethon.<\/strong>\u00a0\u0412 HTML-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445 \u044d\u043c\u043e\u0434\u0437\u0438 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u0433. \u0412 Telethon \u043d\u0443\u0436\u043d\u044b\u00a0<code>MessageEntityCustomEmoji<\/code>\u00a0\u0441\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f\u043c\u0438, \u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u043e\u043d\u0438\u00a0<strong>\u0432 UTF-16<\/strong>, \u0430 \u043d\u0435 \u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0445 Python. \u042d\u043c\u043e\u0434\u0437\u0438 \u0432\u0440\u043e\u0434\u0435 \ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0430\u043c 8 \u0435\u0434\u0438\u043d\u0438\u0446.<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0430\u0449\u0438\u0442\u0430 \u043e\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/strong>\u00a0\u0420\u0435\u043d\u0434\u0435\u0440 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u2014 \u0442\u044f\u0436\u0451\u043b\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u0442\u044f\u0436\u0451\u043b\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0435\u0441\u0442\u044c \u043b\u0438\u043c\u0438\u0442 \u0441\u043e \u0441\u043a\u043e\u043b\u044c\u0437\u044f\u0449\u0438\u043c \u043e\u043a\u043d\u043e\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u043b\u044e\u0441 \u0430\u043d\u0442\u0438\u0444\u043b\u0443\u0434. \u041d\u0430 \u0430\u0434\u043c\u0438\u043d\u043e\u0432 \u043b\u0438\u043c\u0438\u0442\u044b \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043f\u0440\u043e\u0435\u043a\u0442<\/h3>\n<p>\u041a\u043e\u0434 \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d \u043f\u043e \u0442\u0435\u043c \u0436\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u043c, \u0447\u0442\u043e \u0438 \u043c\u0435\u043d\u044e:<\/p>\n<pre><code>app\/\u251c\u2500\u2500 menu.py      \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044b\u251c\u2500\u2500 nft\/         \u043f\u043e\u0434\u0430\u0440\u043a\u0438: parser, render, service, watcher, handlers\u251c\u2500\u2500 stickers\/    \u044d\u043c\u043e\u0434\u0437\u0438 \u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u044b: core, downloader, recolor, emoji_maker, packs, handlers\/\u251c\u2500\u2500 admin\/       \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430, \u0431\u0430\u043d\u044b\u2514\u2500\u2500 common\/      \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 SQLite, \u043b\u0438\u043c\u0438\u0442\u044b, \u0442\u0435\u043a\u0441\u0442\u044b RU\/EN, \u0438\u043a\u043e\u043d\u043a\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p><code>\u251c\u2500\u2500 menu.py      \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044b<\/code><\/p>\n<p><code>\u251c\u2500\u2500 nft\/         \u043f\u043e\u0434\u0430\u0440\u043a\u0438: parser, render, service, watcher, handlers<\/code><\/p>\n<p><code>\u251c\u2500\u2500 stickers\/    \u044d\u043c\u043e\u0434\u0437\u0438 \u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u044b: core, downloader, recolor, emoji_maker, packs, handlers\/<\/code><\/p>\n<p><code>\u251c\u2500\u2500 admin\/       \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430, \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0430, \u0431\u0430\u043d\u044b<\/code><\/p>\n<p><code>\u2514\u2500\u2500 common\/      \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 SQLite, \u043b\u0438\u043c\u0438\u0442\u044b, \u0442\u0435\u043a\u0441\u0442\u044b RU\/EN, \u0438\u043a\u043e\u043d\u043a\u0438<\/code><\/p>\n<p>\u0415\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u044b (pytest, 65 \u0448\u0442\u0443\u043a), ruff \u0438 mypy \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0431\u0435\u0437 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0439. \u0417\u0430\u043f\u0443\u0441\u043a \u2014\u00a0<code>docker compose up -d<\/code>. \u0414\u043b\u044f Windows \u0435\u0441\u0442\u044c\u00a0<code>deploy.bat<\/code>: \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043f\u0430\u0440\u043e\u043b\u044c \u0438 \u0442\u043e\u043a\u0435\u043d, \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u043e SSH, \u0441\u0442\u0430\u0432\u0438\u0442 Docker \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0431\u043e\u0442\u0430. \u041f\u0430\u0440\u043e\u043b\u044c \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<h3>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435<\/h3>\n<ul>\n<li>\n<p>\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u043e\u043d\u0430 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c\u044e (\u0441\u0435\u0439\u0447\u0430\u0441 \u0431\u043e\u0442 \u0441\u0440\u0435\u0437\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0442\u043e\u043d\u043d\u044b\u0439 \u0444\u043e\u043d).<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u044d\u043c\u043e\u0434\u0437\u0438 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u0442\u0430: <a class=\"mention\" href=\"\/users\/EmojiTGSFileBot\">@EmojiTGSFileBot<\/a>. \u041a\u043e\u0434:\u00a0<a href=\"http:\/\/github.com\/alvaro-lox\/emoji-studio-bot\" rel=\"noopener nofollow\">github.com\/alvaro-lox\/emoji-studio-bot<\/a>. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u043c \u0438 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f\u043c \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0435\u0442\u0435, \u043a\u0430\u043a Telegram \u0440\u0438\u0441\u0443\u0435\u0442 \u043f\u043e\u0434\u0430\u0440\u043a\u0438 \u0443 \u0441\u0435\u0431\u044f \u0438 \u0433\u0434\u0435 \u044f \u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b.<\/p>\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\/1101044\/\">https:\/\/habr.com\/ru\/articles\/1101044\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Resistance Dog #14 072 \u2014 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0440\u0438\u0441\u0443\u0435\u0442 \u0431\u043e\u0442\u0412 Telegram \u0435\u0441\u0442\u044c \u043f\u0440\u0435\u043c\u0438\u0443\u043c-\u044d\u043c\u043e\u0434\u0437\u0438, \u043f\u0430\u043a\u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u043e\u0432 \u0438 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0438. \u0412\u0441\u0451 \u044d\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043e\u0442\u0442\u0443\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e. \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043f\u0430\u043a \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043d\u0435\u043b\u044c\u0437\u044f. \u0427\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c\u00a0custom_emoji_id, \u043d\u0443\u0436\u0435\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043e\u0442 \u0438\u043b\u0438 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a. \u0410 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u043d\u0435 Telegram \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441 \u044d\u043a\u0440\u0430\u043d\u0430.\u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0431\u043e\u0442\u0430\u00a0Emoji Studio, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0451 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u2014 \u043d\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e \u0441\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u043e \u0434\u043e\u0440\u043e\u0433\u0435:\u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043f\u043e\u0434\u0430\u0440\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u0443 Telegram \u043d\u0435\u0442 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e API;\u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043a\u0430\u0434\u0440\u043e\u0432 Lottie \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0451\u043c\u043d\u0430\u044f \u043e\u0431\u0432\u043e\u0434\u043a\u0430 \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c;\u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u0437\u044f\u043b\u0441\u044f \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0439 \u043a\u0432\u0430\u0434\u0440\u0430\u0442;\u043a\u0430\u043a \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u043f\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0430\u043b\u0438 \u0442\u0435\u043d\u0438 \u0438 \u0431\u043b\u0438\u043a\u0438.\u0421\u0442\u0435\u043a: Python 3.12, aiogram 3, rlottie-python, numpy, Pillow, ffmpeg, SQLite. \u041a\u043e\u0434 \u043e\u0442\u043a\u0440\u044b\u0442:\u00a0github.com\/alvaro-lox\/emoji-studio-bot.\u0427\u0442\u043e \u0443\u043c\u0435\u0435\u0442 \u0431\u043e\u0442\u041c\u0435\u043d\u044e \u0440\u0430\u0437\u0431\u0438\u0442\u043e \u043d\u0430 \u0434\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430.\ud83e\udde9 \u042d\u043c\u043e\u0434\u0437\u0438 \u0438 \u0441\u0442\u0438\u043a\u0435\u0440\u044b.\u00a0\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c, \u0438 \u0431\u043e\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0451, \u0447\u0442\u043e \u0435\u043c\u0443 \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u044e\u0442:ID \u044d\u043c\u043e\u0434\u0437\u0438\u00a0\u2014\u00a0custom_emoji_id\u00a0\u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043c\u043e\u0434\u0437\u0438, \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u00bb \u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f python-telegram-bot, aiogram, Telethon \u0438 Pyrogram. \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0433\u043e \u043f\u0430\u043a\u0430 \u2014 \u0441\u043f\u0438\u0441\u043e\u043a ID \u0438 JSON-\u0444\u0430\u0439\u043b.\u0421\u043a\u0430\u0447\u0430\u0442\u044c\u00a0\u2014 \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u0440\u0438\u0441\u043b\u0430\u043d\u043e \u043f\u043e\u0434\u0440\u044f\u0434, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043e\u0434\u043d\u0438\u043c zip (.tgs,\u00a0.webm,\u00a0.webp).\u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c\u00a0\u2014 \u043f\u0430\u043a \u0432 \u043b\u044e\u0431\u043e\u0439 \u0446\u0432\u0435\u0442, \u0441 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00ab\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0432 Telegram\u00bb.\u0412 \u043b\u044e\u0431\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0430\u043a \u0434\u0430\u0451\u0442 \u043f\u0440\u0435\u0432\u044c\u044e \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u043a\u0430 \u043e\u0434\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u043e\u0439, \u0430 \u0444\u043e\u0442\u043e, GIF \u0438\u043b\u0438 \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u044d\u043c\u043e\u0434\u0437\u0438 100\u00d7100.\ud83c\udf81 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0438.\u00a0\u041f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0448\u044c\u00a0https:\/\/t.me\/nft\/plushpepe-1\u00a0\u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0448\u044c MP4 \u0432 60 fps, \u043a\u0430\u043a \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u0432 Telegram. \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442 (3:2, 1:1 \u0434\u043b\u044f \u0430\u0432\u0430\u0442\u0430\u0440\u043a\u0438, 9:16 \u0434\u043b\u044f \u0441\u0442\u043e\u0440\u0438\u0441), \u0441\u0432\u043e\u0439 \u0444\u043e\u043d, \u0441\u0432\u043e\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u044c, \u0441\u043a\u0430\u0447\u0430\u0442\u044c GIF \u0438\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c\u00a0.tgs. \u041c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043b\u0435\u0436\u043a\u0443: \u0431\u043e\u0442 \u043d\u0430\u043f\u0438\u0448\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0441\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446.\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e: \u0434\u0432\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u044d\u043c\u043e\u0434\u0437\u0438: ID, \u043a\u043e\u0434, \u0432\u0441\u0435 ID \u043f\u0430\u043a\u0430, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430\u0417\u0430\u0434\u0430\u0447\u0430 1. \u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0430\u0440\u043e\u043a \u0431\u0435\u0437 API\u0412 Bot API \u043d\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u0430 \u00ab\u043e\u0442\u0434\u0430\u0439 \u043c\u043d\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 NFT-\u043f\u043e\u0434\u0430\u0440\u043a\u0430\u00bb. \u0417\u0430\u0442\u043e \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u00a0t.me\/nft\/&lt;slug&gt;, \u0438 Telegram \u0441\u0430\u043c \u0440\u0438\u0441\u0443\u0435\u0442 \u043d\u0430 \u043d\u0435\u0439 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u0415\u0441\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434, \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435:\u0440\u0430\u0434\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u0444\u043e\u043d\u0430 \u2014 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 SVG \u0441\u00a0&lt;stop stop-color=&#187;\u2026&#187;&gt;;\u0443\u0437\u043e\u0440 \u2014 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430-\u043f\u043b\u0438\u0442\u043a\u0430\u00a0#giftPattern\u00a0\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0435\u0451 \u043a\u043e\u043f\u0438\u0439 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u043e\u043c \u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c\u044e;\u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0.tgs\u00a0\u0432\u00a0&lt;source type=&#187;application\/x-tgsticker&#187;&gt;;\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043c\u043e\u0434\u0435\u043b\u044c\u044e, \u0444\u043e\u043d\u043e\u043c, \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c, \u0438\u0445 \u0440\u0435\u0434\u043a\u043e\u0441\u0442\u044c\u044e \u0438 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c.\u0420\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0443 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a:for opacity, x, y, scale in re.findall(    r'&lt;g opacity=&#187;([\\d.]+)&#187; transform=&#187;translate\\(([-\\d.]+),\\s*([-\\d.]+)\\)&#187;&gt;\\s*&#8217;    r'&lt;use xlink:href=&#187;#giftPattern&#187; transform=&#187;scale\\(([\\d.]+)\\)&#187;&#8216;,    html,):    info.pattern.append(PatternItem(float(x), float(y), float(scale), float(opacity)))    r'&lt;g opacity=&#187;([\\d.]+)&#187; transform=&#187;translate\\(([-\\d.]+),\\s*([-\\d.]+)\\)&#187;&gt;\\s*&#8217;    r'&lt;use xlink:href=&#187;#giftPattern&#187; transform=&#187;scale\\(([\\d.]+)\\)&#187;&#8216;,    html,):    info.pattern.append(PatternItem(float(x), float(y), float(scale), float(opacity)))\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0443\u0437\u043e\u0440\u0430 \u0437\u0430\u0434\u0430\u043d\u044b \u0434\u043b\u044f \u0445\u043e\u043b\u0441\u0442\u0430 420\u00d7280, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u043b\u044c\u0448\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u044e \u0438\u0445 \u043f\u043e\u0434 \u043d\u0443\u0436\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440. \u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 9:16 \u0445\u043e\u043b\u0441\u0442 \u0440\u0430\u0441\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0432\u044b\u0441\u043e\u0442\u0435, \u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0443\u0437\u043e\u0440 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443.\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u043e HTML-\u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u2014 \u043e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440. \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f, \u043d\u0443\u0436\u043d\u044b\u0435 \u043a\u0443\u0441\u043a\u0438 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b, \u0430 \u0435\u0441\u043b\u0438 Telegram \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442 \u0432\u0451\u0440\u0441\u0442\u043a\u0443, \u0441\u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0437\u0431\u043e\u0440\u0430. \u0417\u0430\u0442\u043e \u043d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0435\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u044f\u0445 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446.\u0417\u0430\u0434\u0430\u0447\u0430 2. \u0422\u0451\u043c\u043d\u0430\u044f \u043e\u0431\u0432\u043e\u0434\u043a\u0430, \u0438\u043b\u0438 premultiplied alpha\u041c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u2014 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f Lottie. \u041a\u0430\u0434\u0440\u044b \u044f \u043f\u043e\u043b\u0443\u0447\u0430\u044e \u0447\u0435\u0440\u0435\u0437 rlottie (\u0442\u043e\u0442 \u0436\u0435 \u0434\u0432\u0438\u0436\u043e\u043a, \u0447\u0442\u043e \u0438 \u0432 \u0441\u0430\u043c\u043e\u043c Telegram) \u0438 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e \u043d\u0430 \u0444\u043e\u043d \u0432 numpy. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u0435\u043b\u0430\u043b\u0430 \u044d\u0442\u043e \u043f\u043e \u0443\u0447\u0435\u0431\u043d\u0438\u043a\u0443:out = src * a + dst * (1 &#8212; a)\u0418 \u043f\u043e \u043a\u0440\u0430\u044f\u043c \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0433\u0440\u044f\u0437\u043d\u0430\u044f \u0442\u0451\u043c\u043d\u0430\u044f \u043a\u0430\u0439\u043c\u0430. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e rlottie \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u0441\u00a0premultiplied alpha: \u0446\u0432\u0435\u0442 \u0443\u0436\u0435 \u0443\u043c\u043d\u043e\u0436\u0435\u043d \u043d\u0430 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u0443\u043c\u043d\u043e\u0436\u0438\u0442\u044c \u0435\u0433\u043e \u0435\u0449\u0451 \u0440\u0430\u0437, \u043f\u043e\u043b\u0443\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u043d\u0430 \u043a\u0440\u0430\u044f\u0445 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0442\u0435\u043c\u043d\u0435\u0435, \u0447\u0435\u043c \u0434\u043e\u043b\u0436\u043d\u044b. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0430 \u043a\u043e\u0440\u043e\u0447\u0435:# rlottie \u043e\u0442\u0434\u0430\u0451\u0442 premultiplied alpha: out = src + dst * (1 &#8212; a)alpha = model[&#8230;, 3:4] \/ 255.0composed = np.clip(model[&#8230;, :3] + region * (1 &#8212; alpha), 0, 255).astype(np.uint8)alpha = model[&#8230;, 3:4] \/ 255.0composed = np.clip(model[&#8230;, :3] + region * (1 &#8212; alpha), 0, 255).astype(np.uint8)\u0422\u0430 \u0436\u0435 \u043b\u043e\u0432\u0443\u0448\u043a\u0430 \u0435\u0441\u0442\u044c \u0432 Pillow: \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043a\u0430\u0434\u0440\u0430 rlottie \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043a\u0430\u043a\u00a0RGBA, \u043a\u0440\u0430\u044f \u0431\u0443\u0434\u0443\u0442 \u0442\u0451\u043c\u043d\u044b\u043c\u0438. \u041d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a\u00a0RGBa\u00a0(\u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u00aba\u00bb \u2014 \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c premultiplied), \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.\u0417\u0430\u0434\u0430\u0447\u0430 3. 60 fps \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432\u0423 Lottie \u0441\u0432\u043e\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u043e\u0432, \u043e\u0431\u044b\u0447\u043d\u043e 30 \u0438\u043b\u0438 60. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u043e\u0432\u043d\u043e 60 fps, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u044f \u0431\u0435\u0440\u0443 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0435\u0433\u043e \u043d\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u044e:for k in range(frames_out):    index = min(total &#8212; 1, int(k * rate \/ FPS))    if index != last_index:        &#8230;  # \u0440\u0435\u043d\u0434\u0435\u0440 \u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435    bg[vy0:vy1, vx0:vx1] = composed    stdin.write(bg.tobytes())    index = min(total &#8212; 1, int(k * rate \/ FPS))    if index != last_index:        &#8230;  # \u0440\u0435\u043d\u0434\u0435\u0440 \u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435    bg[vy0:vy1, vx0:vx1] = composed    stdin.write(bg.tobytes())\u041a\u0430\u0434\u0440\u044b \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0434\u0438\u0441\u043a: \u0441\u044b\u0440\u044b\u0435 RGB-\u0431\u0430\u0439\u0442\u044b \u0438\u0434\u0443\u0442 \u0441\u0440\u0430\u0437\u0443 \u0432 ffmpeg \u0447\u0435\u0440\u0435\u0437 pipe (-f rawvideo -pix_fmt rgb24 -i -), \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 libx264 \u0441\u00a0crf 18\u00a0\u0438\u00a0+faststart, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e \u0438\u0433\u0440\u0430\u0442\u044c \u0434\u043e \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0424\u043e\u043d \u0441 \u0443\u0437\u043e\u0440\u043e\u043c \u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u0430\u0434\u0440\u0435 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u043f\u043e\u0434 \u043c\u043e\u0434\u0435\u043b\u044c\u044e.\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043c\u0435\u043b\u043e\u0447\u044c \u2014 GIF. \u0412 \u043d\u0451\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u0430\u0434\u0440\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u0442\u044b\u0445 \u0434\u043e\u043b\u044f\u0445 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 60 fps \u0442\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e: 1\/60 \u0441 \u043e\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u0441\u044f \u0434\u043e 0,02 \u0441, \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u0434\u043b\u0438\u0442\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 GIF \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 50 fps, \u0441 \u043f\u0430\u043b\u0438\u0442\u0440\u043e\u0439 \u0447\u0435\u0440\u0435\u0437\u00a0palettegen\/paletteuse, \u0447\u0442\u043e\u0431\u044b \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u043d\u0435 \u0448\u0451\u043b \u043f\u043e\u043b\u043e\u0441\u0430\u043c\u0438.\u0417\u0430\u0434\u0430\u0447\u0430 4. \u041a\u0432\u0430\u0434\u0440\u0430\u0442 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u043e\u0434\u0430\u0440\u043a\u0430\u0421\u0430\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0431\u0430\u0433. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442: \u0432\u043e\u043a\u0440\u0443\u0433 \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u0432\u0438\u0434\u0435\u043d \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0439 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0444\u043e\u043d\u043e\u043c.\u0422\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u043a\u0432\u0430\u0434\u0440\u0430\u0442: \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 Fragment \u043f\u043e\u0432\u0435\u0440\u0445 \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u043e\u043d\u0430\u0412\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435. \u0415\u0441\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u043e\u0434\u0440\u044f\u0434,\u00a0t.me\/nft\/\u2026\u00a0\u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u0430\u0440\u043a\u0430. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0442\u043e\u0436\u0435 \u0436\u0438\u0432\u0451\u0442 \u043d\u0435\u0434\u043e\u043b\u0433\u043e. \u041d\u0430 \u0442\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0443 \u0431\u043e\u0442\u0430 \u0431\u044b\u043b \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u0443\u0442\u044c:\u00a0nft.fragment.com\/gift\/&lt;slug&gt;.tgs.\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Fragment \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u043e\u0442\u0434\u0430\u0451\u0442\u00a0\u043d\u0435 \u043c\u043e\u0434\u0435\u043b\u044c, \u0430 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443: \u0444\u043e\u043d, \u0443\u0437\u043e\u0440 \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0432 \u043e\u0434\u043d\u043e\u043c Lottie-\u0444\u0430\u0439\u043b\u0435. \u0411\u043e\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u043b \u044d\u0442\u0443 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u043f\u043e\u0432\u0435\u0440\u0445 \u0441\u0432\u043e\u0435\u0433\u043e \u0444\u043e\u043d\u0430, \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0441\u044f \u043a\u0432\u0430\u0434\u0440\u0430\u0442. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e: \u0432 \u0443\u0433\u043b\u0430\u0445 \u043a\u0430\u0434\u0440\u0430 \u0438\u0437 Fragment \u0430\u043b\u044c\u0444\u0430 \u043e\u043a\u043e\u043b\u043e 251, \u0430 \u0443 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u2014 0.\u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u044c, \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 Fragment \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e: \u0441\u043b\u043e\u0438 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f\u00a0Background,\u00a0Pattern,\u00a0Color Icon, \u0430 \u0441\u0430\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043b\u0435\u0436\u0438\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0430\u0441\u0441\u0435\u0442\u043e\u043c \u0441 id\u00a0G. \u0417\u043d\u0430\u0447\u0438\u0442, \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0440\u0435\u0437\u0430\u0442\u044c:def extract_fragment_model(tgs: bytes) -&gt; bytes:    &#171;&#187;&#187;Fragment \u043e\u0442\u0434\u0430\u0451\u0442 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0430\u0441\u0441\u0435\u0442 G.&#187;&#187;&#187;    data = json.loads(gzip.decompress(tgs))    assets = {a.get(&#171;id&#187;): a for a in data.get(&#171;assets&#187;, [])}    model = assets.get(&#171;G&#187;)    if not model or not model.get(&#171;layers&#187;):        raise ValueError(&#171;no model asset in fragment tgs&#187;)  # \u043b\u0443\u0447\u0448\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0447\u0435\u043c \u043a\u0432\u0430\u0434\u0440\u0430\u0442    data[&#171;layers&#187;] = model[&#171;layers&#187;]    data[&#171;assets&#187;] = [a for a in data[&#171;assets&#187;] if a.get(&#171;id&#187;) != &#171;G&#187;]    return gzip.compress(json.dumps(data, separators=(&#171;,&#187;, &#171;:&#187;)).encode())    &#171;&#187;&#187;Fragment \u043e\u0442\u0434\u0430\u0451\u0442 \u0432\u0441\u044e \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u2014 \u0430\u0441\u0441\u0435\u0442 G.&#187;&#187;&#187;    data = json.loads(gzip.decompress(tgs))    assets = {a.get(&#171;id&#187;): a for a in data.get(&#171;assets&#187;, [])}    model = assets.get(&#171;G&#187;)    if not model or not model.get(&#171;layers&#187;):        raise ValueError(&#171;no model asset in fragment tgs&#187;)  # \u043b\u0443\u0447\u0448\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u0447\u0435\u043c \u043a\u0432\u0430\u0434\u0440\u0430\u0442    data[&#171;layers&#187;] = model[&#171;layers&#187;]    data[&#171;assets&#187;] = [a for a in data[&#171;assets&#187;] if a.get(&#171;id&#187;) != &#171;G&#187;]    return gzip.compress(json.dumps(data, separators=(&#171;,&#187;, &#171;:&#187;)).encode())\u0418\u0437 \u0442\u043e\u0439 \u0436\u0435 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0446\u0432\u0435\u0442\u0430 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 (\u0441\u043b\u043e\u0439\u00a0Background) \u0438 \u0443\u0437\u043e\u0440 (\u0441\u043b\u043e\u0439\u00a0Pattern). \u0422\u0430\u043a \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 t.me \u043d\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442, \u0431\u043e\u0442 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0440\u0438\u0441\u0443\u0435\u0442 \u043f\u043e\u0434\u0430\u0440\u043e\u043a \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c\u0438 \u0446\u0432\u0435\u0442\u0430\u043c\u0438.\u0418\u0442\u043e\u0433\u043e\u0432\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0442\u0430\u043a\u0430\u044f: \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 t.me, \u043f\u0440\u0438 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0434\u0432\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u0430 \u0441 \u043f\u0430\u0443\u0437\u043e\u0439, \u043f\u043e\u0442\u043e\u043c Fragment. \u00ab\u041f\u043e\u0434\u0430\u0440\u043e\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u00bb \u0431\u043e\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u0430\u0440\u043a\u0430 \u043d\u0435\u0442 \u0438 \u0442\u0430\u043c. \u0423 \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0435\u0441\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f: \u043d\u0435\u0442 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0438 \u0440\u0435\u0434\u043a\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u043d\u0430 10 \u043c\u0438\u043d\u0443\u0442, \u0430 \u0441\u043b\u0435\u0436\u043a\u0430 \u0437\u0430 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u043c \u0438\u0445 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442, \u0438\u043d\u0430\u0447\u0435 \u0431\u043e\u0442 \u043f\u0440\u0438\u0441\u043b\u0430\u043b \u0431\u044b \u043b\u043e\u0436\u043d\u043e\u0435 \u00ab\u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0441\u043c\u0435\u043d\u0438\u043b\u0441\u044f\u00bb.\u0422\u0435\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0435\u0440\u0435\u0436\u0451\u0442 \u044d\u0442\u043e\u0442 \u0431\u0430\u0433, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0432\u0435\u0449\u044c: \u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c, \u0443\u0433\u043b\u044b \u043a\u0430\u0434\u0440\u0430 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435.\u0417\u0430\u0434\u0430\u0447\u0430 5. \u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430 \u0431\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u0438 \u043e\u0431\u044a\u0451\u043c\u0430\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u0438\u0442\u044c \u043f\u0430\u043a \u044d\u043c\u043e\u0434\u0437\u0438 \u0432 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0446\u0432\u0435\u0442\u0430 \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u043b\u043e\u0441\u043a\u0430\u044f \u0437\u0430\u043b\u0438\u0432\u043a\u0430: \u0442\u0435\u043d\u0435\u0439 \u0438 \u0431\u043b\u0438\u043a\u043e\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435\u0442.\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u043a\u0440\u0430\u0441\u043a\u0430 \u0438\u0434\u0451\u0442 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 HLS. \u041e\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u0442\u043e\u043d \u0438 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0430\u00a0\u0441\u0432\u0435\u0442\u043b\u043e\u0442\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f. \u0422\u0435\u043d\u0438 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u0451\u043c\u043d\u044b\u043c\u0438, \u0431\u043b\u0438\u043a\u0438 \u0441\u0432\u0435\u0442\u043b\u044b\u043c\u0438:class Tint:    def __init__(self, hex_color: str):        r, g, b = hex_to_rgb(hex_color)        self.hue, self.light, self.sat = colorsys.rgb_to_hls(r, g, b)    def __call__(self, r: float, g: float, b: float) -&gt; tuple[float, float, float]:        _, light, sat = colorsys.rgb_to_hls(r, g, b)        # \u0441\u0435\u0440\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u0442\u043e\u0436\u0435 \u043e\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c, \u043d\u043e \u0447\u0443\u0442\u044c \u0441\u043b\u0430\u0431\u0435\u0435 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445        new_sat = self.sat * (0.55 + 0.45 * sat)        return colorsys.hls_to_rgb(self.hue, light, new_sat)    def init(self, hex_color: str):        r, g, b = hex_to_rgb(hex_color)        self.hue, self.light, self.sat = colorsys.rgb_to_hls(r, g, b)    def call(self, r: float, g: float, b: float) -&gt; tuple[float, float, float]:        , light, sat = colorsys.rgbto_hls(r, g, b)        # \u0441\u0435\u0440\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u0442\u043e\u0436\u0435 \u043e\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c, \u043d\u043e \u0447\u0443\u0442\u044c \u0441\u043b\u0430\u0431\u0435\u0435 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u0445        new_sat = self.sat  (0.55 + 0.45  sat)        return colorsys.hls_to_rgb(self.hue, light, new_sat)\u0414\u043b\u044f\u00a0.tgs\u00a0\u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0446\u0432\u0435\u0442\u0443 \u0432 JSON Lottie: \u0437\u0430\u043b\u0438\u0432\u043a\u0430\u043c, \u043e\u0431\u0432\u043e\u0434\u043a\u0430\u043c, \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430\u043c (\u0443 \u043d\u0438\u0445 \u0446\u0432\u0435\u0442\u0430 \u043b\u0435\u0436\u0430\u0442 \u043f\u043b\u043e\u0441\u043a\u0438\u043c \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0432\u043f\u0435\u0440\u0435\u043c\u0435\u0448\u043a\u0443 \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c\u0438) \u0438 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u043a\u0430\u0434\u0440\u0430\u043c. \u0414\u043b\u044f\u00a0.webp\u00a0\u2014 \u043f\u043e\u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u043e. \u041f\u0435\u0440\u0435\u043a\u0440\u0430\u0448\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440: \u0431\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437\u00a0createNewStickerSet\u00a0\u0438 \u0434\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0435\u0440\u0435\u0437\u00a0addStickerToSet, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 50 \u0441\u0442\u0438\u043a\u0435\u0440\u043e\u0432.\u0414\u043e\u041f\u043e\u0441\u043b\u0435 (\u0441\u0435\u0440\u044b\u0439)\u0422\u0435\u043d\u0438 \u043d\u0430 \u0448\u0432\u0430\u0445, \u0431\u043b\u0438\u043a\u0438 \u043d\u0430 \u043f\u0443\u0433\u043e\u0432\u0438\u0446\u0430\u0445 \u0438 \u043e\u0431\u044a\u0451\u043c \u0441\u0435\u0440\u0434\u0446\u0430&#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-500807","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/500807","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=500807"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/500807\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=500807"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=500807"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=500807"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}