LOLZ Inline Assistant

inline

目前为 2025-05-04 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name LOLZ Inline Assistant
  3. // @namespace http://tampermonkey.net/
  4. // @namespace http://tampermonkey.net/
  5. // @author @umikud
  6. // @version 1.2
  7. // @description inline
  8. // @match https://*.lolz.live/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. const sectionsDict = {
  17. "Android": "https://lolz.live/forums/437/",
  18. "Apex Legends": "https://lolz.live/forums/apex-legends/",
  19. "Battle.net": "https://lolz.live/forums/688/",
  20. "Battlefield": "https://lolz.live/forums/battlefield-all/",
  21. "Battlefield 1": "https://lolz.live/forums/759/",
  22. "Battlefield 2042": "https://lolz.live/forums/920/",
  23. "Battlefield V": "https://lolz.live/forums/821/",
  24. "C#": "https://lolz.live/forums/97/",
  25. "C/C++": "https://lolz.live/forums/96/",
  26. "Call of Duty": "https://lolz.live/forums/418/",
  27. "Counter-Strike 2": "https://lolz.live/forums/cs2/",
  28. "CrackME / UnpackME": "https://lolz.live/forums/872/",
  29. "DayZ": "https://lolz.live/forums/998/",
  30. "Deadlock": "https://lolz.live/forums/deadlock/",
  31. "Discord": "https://lolz.live/forums/898/",
  32. "Dota 2": "https://lolz.live/forums/dota2/",
  33. "EFT: Arena": "https://lolz.live/forums/1000/",
  34. "Escape from Tarkov": "https://lolz.live/forums/857/",
  35. "FIFA": "https://lolz.live/forums/946/",
  36. "Fortnite": "https://lolz.live/forums/790/",
  37. "Fortnite, Epic Games": "https://lolz.live/forums/800/",
  38. "GTA": "https://lolz.live/forums/981/",
  39. "GTA SAMP": "https://lolz.live/forums/139/",
  40. "GTA V": "https://lolz.live/forums/141/",
  41. "GTA V MODS": "https://lolz.live/forums/669/",
  42. "Genshin Impact": "https://lolz.live/forums/genshin-impact/",
  43. "Go": "https://lolz.live/forums/1016/",
  44. "HTML шаблоны, лендинги": "https://lolz.live/forums/694/",
  45. "HTML, CSS, Javascript": "https://lolz.live/forums/820/",
  46. "Hash": "https://lolz.live/forums/hash/",
  47. "Honkai Star Rail": "https://lolz.live/forums/honkai-star-rail/",
  48. "Kali Linux": "https://lolz.live/forums/713/",
  49. "League of Legends": "https://lolz.live/forums/130/",
  50. "Linux": "https://lolz.live/forums/588/",
  51. "Malware": "https://lolz.live/forums/343/",
  52. "Minecraft": "https://lolz.live/forums/729/",
  53. "Node.js": "https://lolz.live/forums/867/",
  54. "Origin (EA)": "https://lolz.live/forums/origin/",
  55. "Overwatch 2": "https://lolz.live/forums/967/",
  56. "P2P обмены": "https://lolz.live/forums/1001/",
  57. "PHP, MySQL": "https://lolz.live/forums/510/",
  58. "PSN": "https://lolz.live/forums/psn/",
  59. "PUBG": "https://lolz.live/forums/767/",
  60. "Private Keeper, BAS, OB": "https://lolz.live/forums/818/",
  61. "Python": "https://lolz.live/forums/830/",
  62. "Rainbow Six Siege": "https://lolz.live/forums/1036/",
  63. "Roblox": "https://lolz.live/forums/1019/",
  64. "Roblox Studio": "https://lolz.live/forums/1034/",
  65. "Rocket League": "https://lolz.live/forums/869/",
  66. "Rust": "https://lolz.live/forums/rust/",
  67. "S.T.A.L.K.E.R.": "https://lolz.live/forums/560/",
  68. "S.T.A.L.K.E.R. 2": "https://lolz.live/forums/1032/",
  69. "SAMP": "https://lolz.live/forums/690/",
  70. "SEO, продвижение": "https://lolz.live/forums/95/",
  71. "SMM": "https://lolz.live/forums/746/",
  72. "SMM Instagram": "https://lolz.live/forums/748/",
  73. "SMM ВКонтакте": "https://lolz.live/forums/747/",
  74. "SQLI, Dork Parsers": "https://lolz.live/forums/sqli/",
  75. "Social Club": "https://lolz.live/forums/720/",
  76. "Steam": "https://lolz.live/forums/steam/",
  77. "Supercell": "https://lolz.live/forums/892/",
  78. "Team Fortress 2": "https://lolz.live/forums/983/",
  79. "The Finals": "https://lolz.live/forums/982/",
  80. "Uplay": "https://lolz.live/forums/uplay/",
  81. "VR игры": "https://lolz.live/forums/944/",
  82. "Valorant": "https://lolz.live/forums/914/",
  83. "War Thunder": "https://lolz.live/forums/1037/",
  84. "Warface": "https://lolz.live/forums/warface/",
  85. "Wi-Fi": "https://lolz.live/forums/749/",
  86. "Windows": "https://lolz.live/forums/109/",
  87. "World of Tanks": "https://lolz.live/forums/689/",
  88. "YouTube, Twitch": "https://lolz.live/forums/839/",
  89. "Zenless Zone Zero": "https://lolz.live/forums/zenless-zone-zero/",
  90. "iOS": "https://lolz.live/forums/436/",
  91. "macOS": "https://lolz.live/forums/794/",
  92. "miHoYo": "https://lolz.live/forums/990/",
  93. "osu!": "https://lolz.live/forums/870/",
  94. "Авто, мото": "https://lolz.live/forums/961/",
  95. "Автореггеры": "https://lolz.live/forums/267/",
  96. "Авторские курсы": "https://lolz.live/forums/906/",
  97. "Акки с балансом, бонусами": "https://lolz.live/forums/806/",
  98. "Аниме": "https://lolz.live/forums/835/",
  99. "Анонимность": "https://lolz.live/forums/311/",
  100. "Арбитраж": "https://lolz.live/forums/arbitrage/",
  101. "Баги Warface": "https://lolz.live/forums/536/",
  102. "Баги, скрипты Apex Legends": "https://lolz.live/forums/934/",
  103. "Баги, скрипты для Dota 2": "https://lolz.live/forums/227/",
  104. "Базы, запросы с почт": "https://lolz.live/forums/431/",
  105. "Безопасность": "https://lolz.live/forums/745/",
  106. "Бесплатная графика": "https://lolz.live/forums/833/",
  107. "Бесплатная накрутка": "https://lolz.live/forums/851/",
  108. "Бесплатная разработка": "https://lolz.live/forums/1039/",
  109. "Брут, чекеры": "https://lolz.live/forums/110/",
  110. "Буст аккаунтов": "https://lolz.live/forums/664/",
  111. "Валюта Escape from Tarkov": "https://lolz.live/forums/919/",
  112. "Ваше творчество": "https://lolz.live/forums/845/",
  113. "Ваши истории": "https://lolz.live/forums/819/",
  114. "Ваши работы": "https://lolz.live/forums/372/",
  115. "Ваши сайты": "https://lolz.live/forums/838/",
  116. "Веб уязвимости": "https://lolz.live/forums/392/",
  117. "Веб-разработка": "https://lolz.live/forums/85/",
  118. "Вещи, техника": "https://lolz.live/forums/912/",
  119. "Видео Battlefield 1": "https://lolz.live/forums/924/",
  120. "Видео Battlefield 2042": "https://lolz.live/forums/922/",
  121. "Видео Battlefield V": "https://lolz.live/forums/923/",
  122. "Видео DeadLock": "https://lolz.live/forums/1030/",
  123. "Видео GTA V": "https://lolz.live/forums/175/",
  124. "Видео League of Legends": "https://lolz.live/forums/219/",
  125. "Видео Minecraft": "https://lolz.live/forums/204/",
  126. "Видео Rocket League": "https://lolz.live/forums/973/",
  127. "Видео SAMP": "https://lolz.live/forums/171/",
  128. "Видео Valorant": "https://lolz.live/forums/978/",
  129. "Видео Warface": "https://lolz.live/forums/77/",
  130. "Видео World of Tanks": "https://lolz.live/forums/215/",
  131. "Вирусология": "https://lolz.live/forums/752/",
  132. "Вопрос - Ответ": "https://lolz.live/forums/899/",
  133. "Воркеры": "https://lolz.live/forums/workers_deleted/",
  134. "Вторичка": "https://lolz.live/forums/913/",
  135. "Вторичка дедиков, хостингов": "https://lolz.live/forums/932/",
  136. "Вторичка софта": "https://lolz.live/forums/671/",
  137. "Вторичка читов": "https://lolz.live/forums/929/",
  138. "Вязка каналов": "https://lolz.live/forums/948/",
  139. "Гайды Apex Legends": "https://lolz.live/forums/878/",
  140. "Гайды Battlefield 1": "https://lolz.live/forums/887/",
  141. "Гайды Battlefield 2042": "https://lolz.live/forums/921/",
  142. "Гайды Battlefield V": "https://lolz.live/forums/886/",
  143. "Гайды CS2": "https://lolz.live/forums/36/",
  144. "Гайды Call of Duty": "https://lolz.live/forums/881/",
  145. "Гайды DayZ": "https://lolz.live/forums/1020/",
  146. "Гайды DeadLock": "https://lolz.live/forums/1031/",
  147. "Гайды Escape from Tarkov": "https://lolz.live/forums/885/",
  148. "Гайды FIFA": "https://lolz.live/forums/970/",
  149. "Гайды Fortnite": "https://lolz.live/forums/792/",
  150. "Гайды Genshin Impact": "https://lolz.live/forums/891/",
  151. "Гайды Honkai Star Rail": "https://lolz.live/forums/994/",
  152. "Гайды Overwatch 2": "https://lolz.live/forums/968/",
  153. "Гайды PUBG": "https://lolz.live/forums/768/",
  154. "Гайды Rocket League": "https://lolz.live/forums/888/",
  155. "Гайды Rust": "https://lolz.live/forums/883/",
  156. "Гайды SAMP": "https://lolz.live/forums/170/",
  157. "Гайды Supercell": "https://lolz.live/forums/893/",
  158. "Гайды Valorant": "https://lolz.live/forums/917/",
  159. "Гайды Warface": "https://lolz.live/forums/76/",
  160. "Гайды World of Tanks": "https://lolz.live/forums/214/",
  161. "Гайды Zenless Zone Zero": "https://lolz.live/forums/1005/",
  162. "Гайды osu!": "https://lolz.live/forums/877/",
  163. "Гайды по VR играм": "https://lolz.live/forums/959/",
  164. "Гайды по форуму": "https://lolz.live/forums/7/",
  165. "Гайды, рецепты Minecraft": "https://lolz.live/forums/201/",
  166. "Гайды, тактики по Dota 2": "https://lolz.live/forums/228/",
  167. "Гайды, тактики по GTA V": "https://lolz.live/forums/176/",
  168. "Гайды, тактики по LoL": "https://lolz.live/forums/218/",
  169. "Гифты, ключи, балансы Steam": "https://lolz.live/forums/728/",
  170. "Графика": "https://lolz.live/forums/88/",
  171. "Движки, фреймворки": "https://lolz.live/forums/93/",
  172. "Девайсы": "https://lolz.live/forums/837/",
  173. "Дедики, хостинги": "https://lolz.live/forums/763/",
  174. "Дизайн": "https://lolz.live/forums/design/",
  175. "Дополнения": "https://lolz.live/forums/976/",
  176. "Другие игры": "https://lolz.live/forums/816/",
  177. "Другое": "https://lolz.live/forums/815/",
  178. "Жалобы": "https://lolz.live/forums/801/",
  179. "Жизнь форума": "https://lolz.live/forums/4/",
  180. "Завершенные P2P обмены": "https://lolz.live/forums/1013/",
  181. "Завершенные розыгрыши": "https://lolz.live/forums/771/",
  182. "Задания за деньги": "https://lolz.live/forums/834/",
  183. "Игры": "https://lolz.live/forums/682/",
  184. "Инвентарь Steam": "https://lolz.live/forums/726/",
  185. "Инсталлы, крипт": "https://lolz.live/forums/595/",
  186. "Интервью": "https://lolz.live/forums/interviews/",
  187. "Исходники": "https://lolz.live/forums/696/",
  188. "Ищу работу": "https://lolz.live/forums/832/",
  189. "Ищу софт": "https://lolz.live/forums/718/",
  190. "Карты и скины osu!": "https://lolz.live/forums/905/",
  191. "Кино и мультфильмы": "https://lolz.live/forums/873/",
  192. "Кисти, текстуры, градиенты": "https://lolz.live/forums/698/",
  193. "Компьютеры": "https://lolz.live/forums/587/",
  194. "Конкурсы и турниры": "https://lolz.live/forums/107/",
  195. "Конфиги CS2": "https://lolz.live/forums/38/",
  196. "Кошельки, верификация": "https://lolz.live/forums/817/",
  197. "Криптовалюты": "https://lolz.live/forums/780/",
  198. "Крипторы": "https://lolz.live/forums/347/",
  199. "Кулинария": "https://lolz.live/forums/cookery/",
  200. "Логи": "https://lolz.live/forums/810/",
  201. "Модификации World of Tanks": "https://lolz.live/forums/213/",
  202. "Моды SAMP": "https://lolz.live/forums/722/",
  203. "Моды, текстуры для Minecraft": "https://lolz.live/forums/202/",
  204. "Музыкальные утечки": "https://lolz.live/forums/862/",
  205. "Накрутка в соц. сетях": "https://lolz.live/forums/593/",
  206. "Недочеты": "https://lolz.live/forums/bugs/",
  207. "Нейросети": "https://lolz.live/forums/neural-networks/",
  208. "Неоплаченные претензии": "https://lolz.live/forums/918/",
  209. "Новости сайта": "https://lolz.live/forums/265/",
  210. "Обмен средств": "https://lolz.live/forums/805/",
  211. "Озвучка": "https://lolz.live/forums/863/",
  212. "Остальные игры": "https://lolz.live/forums/760/",
  213. "Ответы ЕГЭ и ОГЭ, ЗНО 2025": "https://lolz.live/forums/otvety-ege-oge-25/",
  214. "Оценка товара": "https://lolz.live/forums/381/",
  215. "Палата №8 (Оффтоп)": "https://lolz.live/forums/8/",
  216. "Парсеры": "https://lolz.live/forums/275/",
  217. "Плагины и сборки Minecraft": "https://lolz.live/forums/251/",
  218. "Платные обжалования": "https://lolz.live/forums/paid-appeals/",
  219. "Подарки в соц. сетях": "https://lolz.live/forums/840/",
  220. "Поиск исполнителей": "https://lolz.live/forums/975/",
  221. "Поиск отработчиков": "https://lolz.live/forums/1007/",
  222. "Полезное ПО": "https://lolz.live/forums/1044/",
  223. "Пополнение баланса": "https://lolz.live/forums/1014/",
  224. "Почты": "https://lolz.live/forums/814/",
  225. "Предложения": "https://lolz.live/forums/suggestions/",
  226. "Приватные читы": "https://lolz.live/forums/263/",
  227. "Приватный софт": "https://lolz.live/forums/345/",
  228. "Приём смс": "https://lolz.live/forums/925/",
  229. "Проблемы с VR играми": "https://lolz.live/forums/960/",
  230. "Проблемы с загрузкой аккаунтов": "https://lolz.live/forums/account-upload-issues/",
  231. "Проблемы с игрой Apex Legends": "https://lolz.live/forums/933/",
  232. "Проблемы с игрой Call of Duty": "https://lolz.live/forums/958/",
  233. "Проблемы с игрой DayZ": "https://lolz.live/forums/1029/",
  234. "Проблемы с игрой Escape from Tarkov": "https://lolz.live/forums/941/",
  235. "Проблемы с игрой FIFA": "https://lolz.live/forums/971/",
  236. "Проблемы с игрой Fortnite": "https://lolz.live/forums/987/",
  237. "Проблемы с игрой GTA V": "https://lolz.live/forums/179/",
  238. "Проблемы с игрой Genshin Impact": "https://lolz.live/forums/939/",
  239. "Проблемы с игрой Honkai Star Rail": "https://lolz.live/forums/995/",
  240. "Проблемы с игрой League of Legends": "https://lolz.live/forums/221/",
  241. "Проблемы с игрой Minecraft": "https://lolz.live/forums/205/",
  242. "Проблемы с игрой Rust": "https://lolz.live/forums/942/",
  243. "Проблемы с игрой SAMP": "https://lolz.live/forums/172/",
  244. "Проблемы с игрой Valorant": "https://lolz.live/forums/980/",
  245. "Проблемы с игрой Warface": "https://lolz.live/forums/79/",
  246. "Проблемы с игрой Zenless Zone Zero": "https://lolz.live/forums/1006/",
  247. "Проблемы с игрой osu!": "https://lolz.live/forums/945/",
  248. "Программирование": "https://lolz.live/forums/733/",
  249. "Прокси чекеры": "https://lolz.live/forums/278/",
  250. "Прокси-серверы": "https://lolz.live/forums/1003/",
  251. "Промокоды": "https://lolz.live/forums/897/",
  252. "Прошивки": "https://lolz.live/forums/1047/",
  253. "Психология": "https://lolz.live/forums/903/",
  254. "Работа и услуги": "https://lolz.live/forums/105/",
  255. "Работа с базами": "https://lolz.live/forums/277/",
  256. "Работа с видео": "https://lolz.live/forums/91/",
  257. "Работа с дедиками": "https://lolz.live/forums/374/",
  258. "Работа с логами": "https://lolz.live/forums/926/",
  259. "Работа с текстом": "https://lolz.live/forums/391/",
  260. "Работа с хэшами": "https://lolz.live/forums/586/",
  261. "Раздачи аккаунтов, ключей": "https://lolz.live/forums/21/",
  262. "Раздачи баз": "https://lolz.live/forums/444/",
  263. "Раздачи вещей Steam": "https://lolz.live/forums/849/",
  264. "Раздачи дедиков": "https://lolz.live/forums/762/",
  265. "Раздачи логов": "https://lolz.live/forums/848/",
  266. "Раздачи прокси": "https://lolz.live/forums/566/",
  267. "Раздел для кураторов": "https://lolz.live/forums/911/",
  268. "Рассмотренные вопросы": "https://lolz.live/forums/902/",
  269. "Рассмотренные недочеты": "https://lolz.live/forums/827/",
  270. "Рассмотренные предложения": "https://lolz.live/forums/809/",
  271. "Реверсинг / Assembler": "https://lolz.live/forums/584/",
  272. "Реклама": "https://lolz.live/forums/962/",
  273. "Ресурсы": "https://lolz.live/forums/608/",
  274. "Решенные жалобы": "https://lolz.live/forums/803/",
  275. "Решенные претензии": "https://lolz.live/forums/774/",
  276. "Розыгрыши": "https://lolz.live/forums/contests/",
  277. "Серверы Minecraft": "https://lolz.live/forums/203/",
  278. "Сигны": "https://lolz.live/forums/868/",
  279. "Скрипты сайтов": "https://lolz.live/forums/650/",
  280. "Скрипты, боты": "https://lolz.live/forums/685/",
  281. "Слив фотографий 18+": "https://lolz.live/forums/media-leaks18/",
  282. "Софт": "https://lolz.live/forums/607/",
  283. "Софт для графики": "https://lolz.live/forums/92/",
  284. "Соц. сети": "https://lolz.live/forums/683/",
  285. "Социальная инженерия": "https://lolz.live/forums/743/",
  286. "Социальные сети": "https://lolz.live/forums/757/",
  287. "Спамеры, бомберы": "https://lolz.live/forums/276/",
  288. "Спорт": "https://lolz.live/forums/904/",
  289. "Способы заработка": "https://lolz.live/forums/363/",
  290. "Спроси у ChatGPT": "https://lolz.live/forums/ask-chatgpt/",
  291. "Сталкер: Зов припяти": "https://lolz.live/forums/561/",
  292. "Сталкер: Тень Чернобыля": "https://lolz.live/forums/562/",
  293. "Сталкер: Чистое Небо": "https://lolz.live/forums/563/",
  294. "Статьи": "https://lolz.live/forums/421/",
  295. "Телефоны": "https://lolz.live/forums/435/",
  296. "Тематические вопросы": "https://lolz.live/forums/585/",
  297. "Тестовый раздел": "https://lolz.live/forums/test-forum/",
  298. "Торговля": "https://lolz.live/forums/104/",
  299. "Трафферы": "https://lolz.live/forums/936/",
  300. "Уроки": "https://lolz.live/forums/823/",
  301. "Уроки по анимациям": "https://lolz.live/forums/393/",
  302. "Уроки реверсинга": "https://lolz.live/forums/601/",
  303. "Учеба": "https://lolz.live/forums/853/",
  304. "Фишинг": "https://lolz.live/forums/855/",
  305. "Халява": "https://lolz.live/forums/9/",
  306. "Хостинг, аренда магазина": "https://lolz.live/forums/596/",
  307. "Чек игрового инвентаря": "https://lolz.live/forums/909/",
  308. "Чек криптовалюты": "https://lolz.live/forums/908/",
  309. "Чек логов, баз": "https://lolz.live/forums/597/",
  310. "Читы Apex Legends": "https://lolz.live/forums/828/",
  311. "Читы CS2": "https://lolz.live/forums/785/",
  312. "Читы Call of Duty": "https://lolz.live/forums/901/",
  313. "Читы DayZ": "https://lolz.live/forums/1028/",
  314. "Читы Dota 2": "https://lolz.live/forums/858/",
  315. "Читы Escape from Tarkov": "https://lolz.live/forums/884/",
  316. "Читы Fortnite": "https://lolz.live/forums/791/",
  317. "Читы PUBG": "https://lolz.live/forums/784/",
  318. "Читы Rust": "https://lolz.live/forums/900/",
  319. "Читы SAMP": "https://lolz.live/forums/518/",
  320. "Читы Valorant": "https://lolz.live/forums/916/",
  321. "Читы Warface": "https://lolz.live/forums/75/",
  322. "Читы для Android игр": "https://lolz.live/forums/783/",
  323. "Читы для игр miHoYo": "https://lolz.live/forums/966/",
  324. "Читы, баги Minecraft": "https://lolz.live/forums/200/",
  325. "Читы, баги для GTA V": "https://lolz.live/forums/177/",
  326. "Читы, баги для League of Legends": "https://lolz.live/forums/217/",
  327. "Шип, рефанд": "https://lolz.live/forums/841/",
  328. "Шрифты": "https://lolz.live/forums/697/",
  329. "Юмор": "https://lolz.live/forums/874/",
  330. };
  331.  
  332. const cryptoSymbols = {
  333. btc: 'bitcoin',
  334. eth: 'ethereum',
  335. ton: 'the-open-network',
  336. usdt: 'tether',
  337. usdc: 'usd-coin',
  338. bnb: 'binancecoin',
  339. sol: 'solana',
  340. xrp: 'ripple',
  341. doge: 'dogecoin',
  342. ada: 'cardano',
  343. avax: 'avalanche-2',
  344. trx: 'tron',
  345. shib: 'shiba-inu',
  346. dot: 'polkadot',
  347. matic: 'matic-network',
  348. dai: 'dai',
  349. ltc: 'litecoin',
  350. link: 'chainlink',
  351. op: 'optimism',
  352. arb: 'arbitrum',
  353. near: 'near'
  354. };
  355. const priceCache = {};
  356. const CACHE_TTL = 60000;
  357. let popup = null;
  358. let editor = null;
  359. let debounceTimer = null;
  360.  
  361. function getCaretPositionRect() {
  362. const sel = window.getSelection();
  363. if (!sel.rangeCount) return null;
  364. const range = sel.getRangeAt(0).cloneRange();
  365. const rects = range.getClientRects();
  366. return rects.length ? rects[0] : null;
  367. }
  368.  
  369. function createPopupIfNeeded() {
  370. if (popup) return;
  371. popup = document.createElement('div');
  372. popup.className = 'fr-popup fr-desktop fr-ltr fe-acPopup fr-above fr-active';
  373. popup.style.zIndex = 9999;
  374. popup.style.position = 'absolute';
  375. popup.style.maxWidth = '350px';
  376.  
  377. const scrollWrapper = document.createElement('div');
  378. scrollWrapper.className = 'scroll-wrapper fe-ac fe-ac-user';
  379. scrollWrapper.style.position = 'relative';
  380.  
  381. const scrollContent = document.createElement('div');
  382. scrollContent.className = 'fe-ac fe-ac-user scroll-content';
  383. scrollContent.style.maxHeight = '132px';
  384.  
  385. scrollWrapper.appendChild(scrollContent);
  386. popup.appendChild(scrollWrapper);
  387. document.body.appendChild(popup);
  388. const style = document.createElement('style');
  389. style.textContent = `
  390. .guarantor_block_card_payment {
  391. padding: 4px 8px;
  392. font-weight: bold;
  393. border-radius: 6px;
  394. font-size: 13px;
  395. font-family: -apple-system,BlinkMacSystemFont,'Open Sans','Helvetica Neue',sans-serif;
  396. display: inline-block;
  397. margin-right: 8px;
  398. }
  399.  
  400. .guarantor_block_card_payment.btc_color { color: #D1AC40; background-color: #413D31; }
  401. .guarantor_block_card_payment.eth_color { color: #4093D6; background-color: #313A41; }
  402. .guarantor_block_card_payment.ton_color { color: #40c0d6; background-color: #36474c; }
  403. .guarantor_block_card_payment.usdt_color { color: #26A17B; background-color: #222; }
  404. .guarantor_block_card_payment.usdc_color { color: #2775CA; background-color: #1E1E1E; }
  405. .guarantor_block_card_payment.bnb_color { color: #F3BA2F; background-color: #1E1E1E; }
  406. .guarantor_block_card_payment.sol_color { color: #66F9A1; background-color: #2A2A2A; }
  407. .guarantor_block_card_payment.xrp_color { color: #00AAE4; background-color: #1C1C1C; }
  408. .guarantor_block_card_payment.doge_color { color: #C2A633; background-color: #3A3A3A; }
  409. .guarantor_block_card_payment.ada_color { color: #0033AD; background-color: #202020; }
  410. .guarantor_block_card_payment.avax_color { color: #E84142; background-color: #1F1F1F; }
  411. .guarantor_block_card_payment.trx_color { color: #EF0027; background-color: #191919; }
  412. .guarantor_block_card_payment.shib_color { color: #F55C44; background-color: #2C2C2C; }
  413. .guarantor_block_card_payment.dot_color { color: #E6007A; background-color: #242424; }
  414. .guarantor_block_card_payment.matic_color{ color: #8247E5; background-color: #282828; }
  415. .guarantor_block_card_payment.dai_color { color: #F4B731; background-color: #292929; }
  416. .guarantor_block_card_payment.ltc_color { color: #BEBEBE; background-color: #2E2E2E; }
  417. .guarantor_block_card_payment.link_color { color: #2A5ADA; background-color: #303030; }
  418. .guarantor_block_card_payment.op_color { color: #FF0420; background-color: #1B1B1B; }
  419. .guarantor_block_card_payment.arb_color { color: #28A0F0; background-color: #1D1D1D; }
  420. .guarantor_block_card_payment.near_color { color: #000000; background-color: #F8F8F8; }
  421.  
  422. `;
  423. popup.appendChild(style);
  424.  
  425. }
  426.  
  427. function updatePopup(results, insertCallback, position) {
  428. createPopupIfNeeded();
  429. popup.style.left = `${position.left}px`;
  430. popup.style.top = `${position.top + 20}px`;
  431.  
  432. const scrollContent = popup.querySelector('.scroll-content');
  433. scrollContent.innerHTML = '';
  434.  
  435. results.forEach(r => {
  436. const div = document.createElement('div');
  437. div.className = 'fe-ac-user-result fe-ac-result';
  438. div.innerHTML = r.isHtml
  439. ? r.title
  440. : `<span class="username"><span class="style2">${r.title}</span></span><span class="item">${r.subtitle}</span>`;
  441.  
  442. div.addEventListener('click', (event) => {
  443. event.preventDefault();
  444. event.stopPropagation();
  445. insertCallback(r.insertText);
  446. hidePopup();
  447. });
  448. scrollContent.appendChild(div);
  449. });
  450. }
  451.  
  452. function hidePopup() {
  453. if (popup) popup.remove();
  454. popup = null;
  455. }
  456.  
  457. async function fetchSuggestions(query) {
  458. const results = [];
  459. console.log(query)
  460.  
  461. const calcMatch = query.match(/^([a-z]{2,5})\s*([\*\+\/\-])\s*(\d+(\.\d+)?%?)$/i);
  462. if (calcMatch) {
  463. const [, symbolKey, operator, valueRaw] = calcMatch;
  464. const coinId = cryptoSymbols[symbolKey];
  465. if (coinId) {
  466. const now = Date.now();
  467. let price;
  468.  
  469. const cacheEntry = priceCache[symbolKey];
  470. if (cacheEntry && now - cacheEntry.timestamp < CACHE_TTL) {
  471. price = cacheEntry.price;
  472. } else {
  473. try {
  474. const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=usd`);
  475. const data = await res.json();
  476. price = data[coinId]?.usd;
  477. if (!price) throw new Error();
  478. priceCache[symbolKey] = { price, timestamp: now };
  479. } catch (e) {
  480. console.error('Ошибка получения курс:', e);
  481. }
  482. }
  483.  
  484. if (price) {
  485. const isPercent = valueRaw.endsWith('%');
  486. const value = parseFloat(valueRaw.replace('%', ''));
  487. let result;
  488.  
  489. switch (operator) {
  490. case '*': result = price * value; break;
  491. case '/': result = price / value; break;
  492. case '+': result = isPercent ? price * (1 + value / 100) : price + value; break;
  493. case '-': result = isPercent ? price * (1 - value / 100) : price - value; break;
  494. }
  495.  
  496. const rounded = result.toFixed(2);
  497. results.push({
  498. title: `<span class="guarantor_block_card_payment ${symbolKey}_color">${symbolKey.toUpperCase()} ${rounded} USD</span>`,
  499. subtitle: '',
  500. insertText: `${symbolKey.toUpperCase()}: ${rounded} USD`,
  501. isHtml: true
  502. });
  503. }
  504. return results;
  505. }
  506. }
  507.  
  508.  
  509. if (cryptoSymbols[query]) {
  510. const coinId = cryptoSymbols[query];
  511. const now = Date.now();
  512. let price;
  513.  
  514. const cacheEntry = priceCache[query];
  515. if (cacheEntry && now - cacheEntry.timestamp < CACHE_TTL) {
  516. price = cacheEntry.price;
  517. } else {
  518. try {
  519. const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=usd`);
  520. const data = await res.json();
  521. price = data[coinId]?.usd;
  522. if (!price) throw new Error();
  523. priceCache[query] = { price, timestamp: now };
  524. } catch (e) {
  525. console.error('Ошибка получения курса:', e);
  526. }
  527. }
  528.  
  529. if (price) {
  530. const symbol = query.toUpperCase();
  531. const html = `<span class="guarantor_block_card_payment ${query}_color">${symbol} ${price} USD</span>`;
  532. results.push({
  533. title: html,
  534. subtitle: '',
  535. insertText: `${symbol}: ${price} USD`,
  536. isHtml: true
  537. });
  538. }
  539. }
  540.  
  541. for (const [key, url] of Object.entries(sectionsDict)) {
  542. if (key.toLowerCase().includes(query.toLowerCase())) {
  543. const urlParts = url.split("/");
  544. const last = urlParts.filter(Boolean).pop();
  545. const nodeId = last.match(/^\d+$/) ? `node${last}` : `node_${last}`;
  546. const html = `<span class="internalNodeLink ${nodeId}"><a href="${url}" class="internalLink internalNodeLink ${nodeId}">${key}</a></span>`;
  547. results.push({
  548. title: html,
  549. subtitle: '',
  550. insertText: `${url}`,
  551. isHtml: true
  552. });
  553. }
  554.  
  555. }
  556.  
  557.  
  558. return results;
  559. }
  560.  
  561. function insertTextAtCursor(oldTrigger, newText) {
  562. const sel = window.getSelection();
  563. if (!sel.rangeCount) return;
  564. const node = sel.anchorNode;
  565. if (!node || !node.textContent) return;
  566.  
  567. const text = node.textContent;
  568. const replaced = text.replace(oldTrigger, newText + ' ');
  569. node.textContent = replaced;
  570.  
  571. const range = document.createRange();
  572. range.setStart(node, replaced.length);
  573. range.setEnd(node, replaced.length);
  574. sel.removeAllRanges();
  575. sel.addRange(range);
  576. }
  577.  
  578. function handleKeyup(e) {
  579. if (debounceTimer) clearTimeout(debounceTimer);
  580.  
  581. debounceTimer = setTimeout(async () => {
  582. const sel = window.getSelection();
  583. if (!sel.rangeCount) return;
  584. const node = sel.anchorNode;
  585. if (!node || !node.textContent) return;
  586.  
  587. const text = node.textContent;
  588. const match = text.match(/!([\p{L}\p{N}\s\-\+\*\/%.,]{2,40})$/u);
  589. if (match) {
  590. const query = match[1].toLowerCase();
  591. const caretRect = getCaretPositionRect();
  592. if (!caretRect) return;
  593. const suggestions = await fetchSuggestions(query);
  594. if (suggestions.length) {
  595. updatePopup(suggestions, (txt) => insertTextAtCursor('!' + query, txt), caretRect);
  596. } else {
  597. hidePopup();
  598. }
  599. } else {
  600. hidePopup();
  601. }
  602. }, 250);
  603. }
  604.  
  605. function setup() {
  606. if (editor) return;
  607. editor = document.querySelector('.fr-element[contenteditable="true"]');
  608. if (editor) {
  609. editor.addEventListener('keyup', handleKeyup);
  610. }
  611. }
  612.  
  613. const observer = new MutationObserver(() => setup());
  614. observer.observe(document.body, { childList: true, subtree: true });
  615.  
  616. window.addEventListener('load', setup);
  617. })();