GithubCard

生成Github的简介卡片

  1. // ==UserScript==
  2. // @name GithubCard
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description 生成Github的简介卡片
  6. // @connect avatars.githubusercontent.com
  7. // @grant GM_xmlhttpRequest
  8. // @author ljs-2002
  9. // @icon https://github.githubassets.com/favicons/favicon.svg
  10. // @match https://github.com/*/*
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. class _repoName {
  17. constructor(ownerName, repoName) {
  18. this.ownerName = ownerName,
  19. this.repoName = repoName,
  20. this.fullName = ownerName + '/' + repoName
  21. }
  22.  
  23. url() {
  24. return "https://api.github.com/repos/" + this.fullName
  25. }
  26. }
  27.  
  28. async function getFromAPI(url, type) {
  29. try {
  30. const response = await fetch(url);
  31. const data = await response.json();
  32. return data; // 使用async/await来获取解决值并作为函数a()的返回值
  33. } catch (error) {
  34. console.error("请求出错:", error);
  35. throw error; // 在此抛出错误,以确保调用函数的地方可以捕获到错误
  36. }
  37. }
  38.  
  39. class GithubInfo {
  40. constructor(info_dict) {
  41.  
  42. this.repo_name = info_dict.name
  43. this.repo_href = info_dict.html_url
  44. this.tag_href = this.repo_href + '/tags'
  45. this.star_href = this.repo_href + '/stargazers'
  46. this.fork_href = this.repo_href + '/forks'
  47. this.owner = info_dict.owner
  48. this.description = info_dict.description
  49. this.stars_count = String(info_dict.stargazers_count)
  50. this.language = info_dict.language
  51. this.forks_count = String(info_dict.forks_count)
  52. this.license = info_dict.license ? info_dict.license.spdx_id : undefined
  53. if (this.license !== undefined){
  54. this.license_href = this.repo_href + '/blob/' + info_dict.default_branch + '/LICENSE'
  55. if(this.license === 'NOASSERTION'){
  56. this.license = 'Custom-License'
  57. }
  58. }
  59. this.tag_count ='0'
  60. this.topics = info_dict.topics
  61.  
  62. }
  63.  
  64. }
  65.  
  66. function getRepoName() {
  67. var owner_repo = /github.com\/([^/]+)\/([^/]+)/i
  68. // 获取当前页面的URL
  69. var currentUrl = window.location.href;
  70. var matches = currentUrl.match(owner_repo)
  71. if (matches) {
  72. var ownerName = matches[1]
  73. var repoName = matches[2]
  74. }else{
  75. throw new Error("can't matches current repo name!")
  76. }
  77. return new _repoName(ownerName, repoName)
  78. }
  79.  
  80. function renderEmoji(desc) {
  81. // Split the string using lookbehind and lookahead regex pattern
  82. const chunks = desc.split(/(?<=\s)|(?=\s)/);
  83. // Define a dictionary mapping symbols to emojis (assuming it's defined somewhere in the code)
  84. const emoji = {":+1:": "👍", ":100:": "💯", ":1234:": "🔢",
  85. ":8ball:": "🎱", ":a:": "🅰️", ":ab:": "🆎",
  86. ":abc:": "🔤", ":abcd:": "🔡", ":accept:": "🉑",
  87. ":aerial_tramway:": "🚡", ":airplane:": "✈️",
  88. ":alarm_clock:": "⏰", ":alien:": "👽",
  89. ":ambulance:": "🚑", ":anchor:": "⚓️",
  90. ":angel:": "👼", ":anger:": "💢",
  91. ":angry:": "😠", ":anguished:": "😧",
  92. ":ant:": "🐜", ":apple:": "🍎",
  93. ":aquarius:": "♒️", ":aries:": "♈️",
  94. ":arrow_backward:": "◀️", ":arrow_double_down:": "⏬",
  95. ":arrow_double_up:": "⏫", ":arrow_down:": "⬇️",
  96. ":arrow_down_small:": "🔽", ":arrow_forward:": "▶️",
  97. ":arrow_heading_down:": "⤵️", ":arrow_heading_up:": "⤴️",
  98. ":arrow_left:": "⬅️", ":arrow_lower_left:": "↙️",
  99. ":arrow_lower_right:": "↘️", ":arrow_right:": "➡️",
  100. ":arrow_right_hook:": "↪️", ":arrow_up:": "⬆️",
  101. ":arrow_up_down:": "↕️", ":arrow_up_small:": "🔼",
  102. ":arrow_upper_left:": "↖️", ":arrow_upper_right:": "↗️",
  103. ":arrows_clockwise:": "🔃", ":arrows_counterclockwise:": "🔄",
  104. ":art:": "🎨", ":articulated_lorry:": "🚛", ":astonished:": "😲",
  105. ":athletic_shoe:": "👟", ":atm:": "🏧", ":b:": "🅱️", ":baby:": "👶",
  106. ":baby_bottle:": "🍼", ":baby_chick:": "🐤", ":baby_symbol:": "🚼",
  107. ":back:": "🔙", ":baggage_claim:": "🛄", ":balloon:": "🎈",
  108. ":ballot_box_with_check:": "☑️", ":bamboo:": "🎍",
  109. ":banana:": "🍌", ":bangbang:": "‼️", ":bank:": "🏦",
  110. ":bar_chart:": "📊", ":barber:": "💈", ":baseball:": "⚾️",
  111. ":basketball:": "🏀", ":bath:": "🛀", ":bathtub:": "🛁",
  112. ":battery:": "🔋", ":bear:": "🐻", ":bee:": "🐝", ":beer:": "🍺",
  113. ":beers:": "🍻", ":beetle:": "🐞", ":beginner:": "🔰", ":bell:": "🔔",
  114. ":bento:": "🍱", ":bicyclist:": "🚴", ":bike:": "🚲", ":bikini:": "👙",
  115. ":bird:": "🐦", ":birthday:": "🎂", ":black_circle:": "⚫️",
  116. ":black_joker:": "🃏", ":black_large_square:": "⬛️",
  117. ":black_medium_small_square:": "◾️", ":black_medium_square:": "◼️",
  118. ":black_nib:": "✒️", ":black_small_square:": "▪️",
  119. ":black_square_button:": "🔲", ":blossom:": "🌼",
  120. ":blowfish:": "🐡", ":blue_book:": "📘", ":blue_car:": "🚙",
  121. ":blue_heart:": "💙", ":blush:": "😊", ":boar:": "🐗",
  122. ":boat:": "⛵️", ":bomb:": "💣", ":book:": "📖", ":bookmark:": "🔖",
  123. ":bookmark_tabs:": "📑", ":books:": "📚", ":boom:": "💥",
  124. ":boot:": "👢", ":bouquet:": "💐", ":bow:": "🙇",
  125. ":bow_and_arrow:": "🏹", ":bowing_man:": "🙇",
  126. ":bowing_woman:": "🙇\u200D♀", ":bowling:": "🎳",
  127. ":bowtie:": "", ":boy:": "👦", ":bread:": "🍞",
  128. ":bride_with_veil:": "👰", ":bridge_at_night:": "🌉",
  129. ":briefcase:": "💼", ":broken_heart:": "💔", ":bug:": "🐛",
  130. ":bulb:": "💡", ":bullettrain_front:": "🚅",
  131. ":bullettrain_side:": "🚄", ":bus:": "🚌", ":busstop:": "🚏",
  132. ":bust_in_silhouette:": "👤", ":busts_in_silhouette:": "👥",
  133. ":cactus:": "🌵", ":cake:": "🍰", ":calendar:": "📆",
  134. ":calling:": "📲", ":camel:": "🐫", ":camera:": "📷", ":canada:": "🇨🇦",
  135. ":canary_islands:": "🇮🇨", ":cancer:": "♋️",
  136. ":candle:": "🕯", ":candy:": "🍬", ":capital_abcd:": "🔠",
  137. ":capricorn:": "♑️", ":car:": "🚗", ":card_index:": "📇",
  138. ":carousel_horse:": "🎠", ":cat:": "🐱", ":cat2:": "🐈",
  139. ":cd:": "💿", ":chart:": "💹", ":chart_with_downwards_trend:": "📉",
  140. ":chart_with_upwards_trend:": "📈", ":checkered_flag:": "🏁",
  141. ":cherries:": "🍒", ":cherry_blossom:": "🌸", ":chestnut:": "🌰",
  142. ":chicken:": "🐔", ":children_crossing:": "🚸", ":chocolate_bar:": "🍫",
  143. ":christmas_tree:": "🎄", ":church:": "⛪️", ":cinema:": "🎦",
  144. ":circus_tent:": "🎪", ":city_sunrise:": "🌇", ":city_sunset:": "🌆",
  145. ":cl:": "🆑", ":clap:": "👏", ":clapper:": "🎬", ":clipboard:": "📋",
  146. ":clock1:": "🕐", ":clock10:": "🕙", ":clock1030:": "🕥",
  147. ":clock11:": "🕚", ":clock1130:": "🕦", ":clock12:": "🕛",
  148. ":clock1230:": "🕧", ":clock130:": "🕜", ":clock2:": "🕑",
  149. ":clock230:": "🕝", ":clock3:": "🕒", ":clock330:": "🕞",
  150. ":clock4:": "🕓", ":clock430:": "🕟", ":clock5:": "🕔",
  151. ":clock530:": "🕠", ":clock6:": "🕕", ":clock630:": "🕡",
  152. ":clock7:": "🕖", ":clock730:": "🕢", ":clock8:": "🕗",
  153. ":clock830:": "🕣", ":clock9:": "🕘", ":clock930:": "🕤",
  154. ":closed_book:": "📕", ":closed_lock_with_key:": "🔐",
  155. ":closed_umbrella:": "🌂", ":cloud:": "☁️", ":clubs:": "♣️",
  156. ":cn:": "🇨🇳", ":cocktail:": "🍸", ":coffee:": "☕️", ":cold_sweat:": "😰",
  157. ":collision:": "💥", ":computer:": "💻", ":confetti_ball:":
  158. "🎊", ":confounded:": "😖", ":confused:": "😕", ":congratulations:": "㊗️",
  159. ":construction:": "🚧", ":construction_worker:": "👷",
  160. ":convenience_store:": "🏪", ":cookie:": "🍪", ":cool:": "🆒",
  161. ":cop:": "👮", ":copyright:": "©️", ":corn:": "🌽", ":couple:": "👫",
  162. ":couple_with_heart:": "💑", ":cow:": "🐮", ":cow2:": "🐄",
  163. ":credit_card:": "💳", ":crescent_moon:": "🌙", ":crocodile:": "🐊",
  164. ":crossed_flags:": "🎌", ":crown:": "👑", ":cry:": "😢",
  165. ":crying_cat_face:": "😿", ":crystal_ball:": "🔮", ":cupid:": "💘",
  166. ":curly_loop:": "➰", ":currency_exchange:": "💱", ":curry:": "🍛",
  167. ":custard:": "🍮", ":customs:": "🛃", ":cyclone:": "🌀", ":dancer:": "💃",
  168. ":dancers:": "👯", ":dango:": "🍡", ":dart:": "🎯", ":dash:": "💨",
  169. ":date:": "📅", ":de:": "🇩🇪", ":deciduous_tree:": "🌳",
  170. ":department_store:": "🏬", ":diamond_shape_with_a_dot_inside:": "💠",
  171. ":diamonds:": "♦️", ":disappointed:": "😞", ":disappointed_relieved:": "😥",
  172. ":dizzy:": "💫", ":dizzy_face:": "😵", ":do_not_litter:": "🚯",
  173. ":dog:": "🐶", ":dog2:": "🐕", ":dollar:": "💵", ":dolls:": "🎎",
  174. ":dolphin:": "🐬", ":door:": "🚪", ":doughnut:": "🍩", ":dragon:": "🐉",
  175. ":dragon_face:": "🐲", ":dress:": "👗", ":dromedary_camel:": "🐪",
  176. ":droplet:": "💧", ":dvd:": "📀", ":e-mail:": "📧", ":ear:": "👂",
  177. ":ear_of_rice:": "🌾", ":earth_africa:": "🌍", ":earth_americas:": "🌎",
  178. ":earth_asia:": "🌏", ":egg:": "🥚", ":eggplant:": "🍆", ":eight:": "8️⃣",
  179. ":eight_pointed_black_star:": "✴️", ":eight_spoked_asterisk:": "✳️",
  180. ":electric_plug:": "🔌", ":elephant:": "🐘", ":email:": "✉️",
  181. ":end:": "🔚", ":envelope:": "✉️", ":envelope_with_arrow:": "📩",
  182. ":es:": "🇪🇸", ":euro:": "💶", ":european_castle:": "🏰",
  183. ":european_post_office:": "🏤", ":evergreen_tree:": "🌲",
  184. ":exclamation:": "❗️", ":expressionless:": "😑", ":eyeglasses:": "👓",
  185. ":eyes:": "👀", ":facepunch:": "👊", ":factory:": "🏭",
  186. ":fallen_leaf:": "🍂", ":family:": "👪", ":fast_forward:": "⏩",
  187. ":fax:": "📠", ":fearful:": "😨", ":feelsgood:": "",
  188. ":feet:": "🐾", ":ferris_wheel:": "🎡", ":file_folder:": "📁",
  189. ":finnadie:": "", ":fire:": "🔥", ":fire_engine:": "🚒",
  190. ":fireworks:": "🎆", ":first_quarter_moon:": "🌓", ":first_quarter_moon_with_face:": "🌛",
  191. ":fish:": "🐟", ":fish_cake:": "🍥", ":fishing_pole_and_fish:": "🎣", ":fist:": "✊",
  192. ":five:": "5️⃣", ":flags:": "🎏", ":flashlight:": "🔦", ":flipper:": "🐬",
  193. ":floppy_disk:": "💾", ":flower_playing_cards:": "🎴", ":flushed:": "😳",
  194. ":foggy:": "🌁", ":football:": "🏈", ":footprints:": "👣", ":fork_and_knife:": "🍴",
  195. ":fountain:": "⛲️", ":four:": "4️⃣", ":four_leaf_clover:": "🍀", ":fr:": "🇫🇷",
  196. ":free:": "🆓", ":fried_shrimp:": "🍤", ":fries:": "🍟", ":frog:": "🐸",
  197. ":frowning:": "😦", ":fu:": "🖕", ":fuelpump:": "⛽️", ":full_moon:": "🌕",
  198. ":full_moon_with_face:": "🌝", ":game_die:": "🎲", ":gb:": "🇬🇧", ":gem:": "💎",
  199. ":gemini:": "♊️", ":ghost:": "👻", ":gift:": "🎁", ":gift_heart:": "💝",
  200. ":girl:": "👧", ":globe_with_meridians:": "🌐", ":goat:": "🐐", ":goberserk:": "",
  201. ":godmode:": "", ":golf:": "⛳️", ":grapes:": "🍇", ":green_apple:": "🍏", ":green_book:": "📗",
  202. ":green_heart:": "💚", ":grey_exclamation:": "❕", ":grey_question:": "❔", ":grimacing:": "😬", ":grin:": "😁",
  203. ":grinning:": "😀", ":guardsman:": "💂", ":guitar:": "🎸", ":gun:": "🔫", ":haircut:": "💇", ":hamburger:": "🍔",
  204. ":hammer:": "🔨", ":hamster:": "🐹", ":hand:": "✋", ":handbag:": "👜", ":hankey:": "💩", ":hash:": "#️⃣", ":hatched_chick:": "🐥",
  205. ":hatching_chick:": "🐣", ":headphones:": "🎧", ":hear_no_evil:": "🙉", ":heart:": "❤️", ":heart_decoration:": "💟",
  206. ":heart_eyes:": "😍", ":heart_eyes_cat:": "😻", ":heartbeat:": "💓", ":heartpulse:": "💗", ":hearts:": "♥️",
  207. ":heavy_check_mark:": "✔️", ":heavy_division_sign:": "➗", ":heavy_dollar_sign:": "💲", ":heavy_exclamation_mark:": "❗️",
  208. ":heavy_minus_sign:": "➖", ":heavy_multiplication_x:": "✖️", ":heavy_plus_sign:": "➕",
  209. ":helicopter:": "🚁", ":herb:": "🌿", ":hibiscus:": "🌺", ":high_brightness:": "🔆",
  210. ":high_heel:": "👠", ":hocho:": "🔪", ":honey_pot:": "🍯", ":honeybee:": "🐝", ":horse:": "🐴",
  211. ":horse_racing:": "🏇", ":hospital:": "🏥", ":hotel:": "🏨", ":hotsprings:": "♨️", ":hourglass:": "⌛️",
  212. ":hourglass_flowing_sand:": "⏳", ":house:": "🏠", ":house_with_garden:": "🏡", ":hurtrealbad:": "",
  213. ":hushed:": "😯", ":ice_cream:": "🍨", ":icecream:": "🍦", ":id:": "🆔", ":ideograph_advantage:": "🉐",
  214. ":imp:": "👿", ":inbox_tray:": "📥", ":incoming_envelope:": "📨", ":information_desk_person:": "💁",
  215. ":information_source:": "ℹ️", ":innocent:": "😇", ":interrobang:": "⁉️", ":iphone:": "📱", ":it:": "🇮🇹",
  216. ":izakaya_lantern:": "🏮", ":jack_o_lantern:": "🎃", ":japan:": "🗾", ":japanese_castle:": "🏯", ":japanese_goblin:": "👺",
  217. ":japanese_ogre:": "👹", ":jeans:": "👖", ":joy:": "😂", ":joy_cat:": "😹", ":jp:": "🇯🇵", ":key:": "🔑",
  218. ":keycap_ten:": "🔟", ":kimono:": "👘", ":kiss:": "💋", ":kissing:": "😗", ":kissing_cat:": "😽",
  219. ":kissing_closed_eyes:": "😚", ":kissing_heart:": "😘", ":kissing_smiling_eyes:": "😙", ":koala:": "🐨",
  220. ":koko:": "🈁", ":kr:": "🇰🇷", ":lantern:": "🏮", ":large_blue_circle:": "🔵", ":large_blue_diamond:": "🔷",
  221. ":large_orange_diamond:": "🔶", ":last_quarter_moon:": "🌗", ":last_quarter_moon_with_face:": "🌜",
  222. ":laughing:": "😆", ":leaves:": "🍃", ":ledger:": "📒", ":left_luggage:": "🛅", ":left_right_arrow:": "↔️",
  223. ":leftwards_arrow_with_hook:": "↩️", ":lemon:": "🍋", ":leo:": "♌️", ":leopard:": "🐆", ":libra:": "♎️",
  224. ":light_rail:": "🚈", ":link:": "🔗", ":lips:": "👄", ":lipstick:": "💄", ":lock:": "🔒",
  225. ":lock_with_ink_pen:": "🔏", ":lollipop:": "🍭", ":loop:": "➿", ":loud_sound:": "🔊",
  226. ":loudspeaker:": "📢", ":love_hotel:": "🏩", ":love_letter:": "💌", ":low_brightness:": "🔅",
  227. ":m:": "Ⓜ️", ":mag:": "🔍", ":mag_right:": "🔎", ":mahjong:": "🀄️", ":mailbox:": "📫",
  228. ":mailbox_closed:": "📪", ":mailbox_with_mail:": "📬", ":mailbox_with_no_mail:": "📭",
  229. ":man:": "👨", ":man_with_gua_pi_mao:": "👲", ":man_with_turban:": "👳", ":mans_shoe:": "👞",
  230. ":maple_leaf:": "🍁", ":mask:": "😷", ":massage:": "💆", ":meat_on_bone:": "🍖", ":mega:": "📣",
  231. ":melon:": "🍈", ":memo:": "📝", ":mens:": "🚹", ":metal:": "🤘", ":metro:": "🚇", ":microphone:":
  232. "🎤", ":microscope:": "🔬", ":milky_way:": "🌌", ":minibus:": "🚐", ":minidisc:": "💽",
  233. ":mobile_phone_off:": "📴", ":money_with_wings:": "💸", ":moneybag:": "💰", ":monkey:": "🐒",
  234. ":monkey_face:": "🐵", ":monorail:": "🚝", ":moon:": "🌔", ":mortar_board:": "🎓", ":mount_fuji:": "🗻",
  235. ":mountain_bicyclist:": "🚵", ":mountain_cableway:": "🚠", ":mountain_railway:": "🚞", ":mouse:": "🐭",
  236. ":mouse2:": "🐁", ":movie_camera:": "🎥", ":moyai:": "🗿", ":muscle:": "💪", ":mushroom:": "🍄",
  237. ":musical_keyboard:": "🎹", ":musical_note:": "🎵", ":musical_score:": "🎼", ":mute:": "🔇", ":nail_care:":
  238. "💅", ":name_badge:": "📛", ":neckbeard:": "", ":necktie:": "👔", ":negative_squared_cross_mark:":
  239. "❎", ":neutral_face:": "😐", ":new:": "🆕", ":new_moon:": "🌑", ":new_moon_with_face:": "🌚", ":newspaper:":
  240. "📰", ":ng:": "🆖", ":night_with_stars:": "🌃", ":nine:": "9️⃣", ":no_bell:": "🔕", ":no_bicycles:": "🚳",
  241. ":no_entry:": "⛔️", ":no_entry_sign:": "🚫", ":no_good:": "🙅", ":no_mobile_phones:": "📵", ":no_mouth:": "😶",
  242. ":no_pedestrians:": "🚷", ":no_smoking:": "🚭", ":non-potable_water:": "🚱", ":nose:": "👃", ":notebook:": "📓",
  243. ":notebook_with_decorative_cover:": "📔", ":notes:": "🎶", ":nut_and_bolt:": "🔩", ":o:": "⭕️", ":o2:": "🅾️",
  244. ":ocean:": "🌊", ":octocat:": "", ":octopus:": "🐙", ":oden:": "🍢", ":office:": "🏢", ":ok:": "🆗",
  245. ":ok_hand:": "👌", ":ok_woman:": "🙆", ":older_man:": "👴", ":older_woman:": "👵", ":on:": "🔛",
  246. ":oncoming_automobile:": "🚘", ":oncoming_bus:": "🚍", ":oncoming_police_car:": "🚔", ":oncoming_taxi:": "🚖",
  247. ":one:": "1️⃣", ":open_book:": "📖", ":open_file_folder:": "📂", ":open_hands:": "👐", ":open_mouth:": "😮",
  248. ":ophiuchus:": "⛎", ":orange_book:": "📙", ":outbox_tray:": "📤", ":ox:": "🐂", ":package:": "📦",
  249. ":page_facing_up:": "📄", ":page_with_curl:": "📃", ":pager:": "📟", ":palm_tree:": "🌴", ":panda_face:": "🐼",
  250. ":paperclip:": "📎", ":parking:": "🅿️", ":part_alternation_mark:": "〽️", ":partly_sunny:": "⛅️",
  251. ":passport_control:": "🛂", ":paw_prints:": "🐾", ":peach:": "🍑", ":pear:": "🍐", ":pencil:": "📝",
  252. ":pencil2:": "✏️", ":penguin:": "🐧", ":pensive:": "😔", ":performing_arts:": "🎭", ":persevere:": "😣",
  253. ":person_frowning:": "🙍", ":person_with_blond_hair:": "👱", ":person_with_pouting_face:": "🙎", ":phone:": "☎️",
  254. ":pig:": "🐷", ":pig2:": "🐖", ":pig_nose:": "🐽", ":pill:": "💊", ":pineapple:": "🍍", ":pisces:": "♓️",
  255. ":pizza:": "🍕", ":point_down:": "👇", ":point_left:": "👈", ":point_right:": "👉", ":point_up:": "☝️",
  256. ":point_up_2:": "👆", ":police_car:": "🚓", ":poodle:": "🐩", ":poop:": "💩", ":post_office:": "🏣",
  257. ":postal_horn:": "📯", ":postbox:": "📮", ":potable_water:": "🚰", ":pouch:": "👝", ":poultry_leg:": "🍗",
  258. ":pound:": "💷", ":pouting_cat:": "😾", ":pray:": "🙏", ":princess:": "👸", ":punch:": "👊",
  259. ":purple_heart:": "💜", ":purse:": "👛", ":pushpin:": "📌", ":put_litter_in_its_place:": "🚮", ":question:": "❓",
  260. ":rabbit:": "🐰", ":rabbit2:": "🐇", ":racehorse:": "🐎", ":radio:": "📻", ":radio_button:": "🔘",
  261. ":rage:": "😡", ":rage1:": "", ":rage2:": "", ":rage3:": "", ":rage4:": "",
  262. ":railway_car:": "🚃", ":rainbow:": "🌈", ":raised_hand:": "✋", ":raised_hands:": "🙌", ":raising_hand:": "🙋",
  263. ":ram:": "🐏", ":ramen:": "🍜", ":rat:": "🐀", ":recycle:": "♻️", ":red_car:": "🚗", ":red_circle:": "🔴",
  264. ":registered:": "®️", ":relaxed:": "☺️", ":relieved:": "😌", ":repeat:": "🔁", ":repeat_one:": "🔂",
  265. ":restroom:": "🚻", ":revolving_hearts:": "💞", ":rewind:": "⏪", ":ribbon:": "🎀", ":rice:": "🍚",
  266. ":rice_ball:": "🍙", ":rice_cracker:": "🍘", ":rice_scene:": "🎑", ":ring:": "💍", ":rocket:": "🚀",
  267. ":roller_coaster:": "🎢", ":rooster:": "🐓", ":rose:": "🌹", ":rotating_light:": "🚨", ":round_pushpin:": "📍",
  268. ":rowboat:": "🚣", ":ru:": "🇷🇺", ":rugby_football:": "🏉", ":runner:": "🏃", ":running:": "🏃",
  269. ":running_shirt_with_sash:": "🎽", ":sa:": "🈂️", ":sagittarius:": "♐️", ":sailboat:": "⛵️",
  270. ":sake:": "🍶", ":sandal:": "👡", ":santa:": "🎅", ":satellite:": "📡", ":satisfied:": "😆",
  271. ":saxophone:": "🎷", ":school:": "🏫", ":school_satchel:": "🎒", ":scissors:": "✂️", ":scorpius:": "♏️",
  272. ":scream:": "😱", ":scream_cat:": "🙀", ":scroll:": "📜", ":seat:": "💺", ":secret:": "㊙️", ":see_no_evil:": "🙈",
  273. ":seedling:": "🌱", ":seven:": "7️⃣", ":shaved_ice:": "🍧", ":sheep:": "🐑", ":shell:": "🐚", ":ship:": "🚢",
  274. ":shipit:": "", ":shirt:": "👕", ":shit:": "💩", ":shoe:": "👞", ":shower:": "🚿", ":signal_strength:": "📶",
  275. ":six:": "6️⃣", ":six_pointed_star:": "🔯", ":ski:": "🎿", ":skull:": "💀", ":sleeping:": "😴", ":sleepy:": "😪",
  276. ":slot_machine:": "🎰", ":small_blue_diamond:": "🔹", ":small_orange_diamond:": "🔸", ":small_red_triangle:": "🔺",
  277. ":small_red_triangle_down:": "🔻", ":smile:": "😄", ":smile_cat:": "😸", ":smiley:": "😃", ":smiley_cat:": "😺",
  278. ":smiling_imp:": "😈", ":smirk:": "😏", ":smirk_cat:": "😼", ":smoking:": "🚬", ":snail:": "🐌", ":snake:": "🐍",
  279. ":snowboarder:": "🏂", ":snowflake:": "❄️", ":snowman:": "⛄️", ":sob:": "😭", ":soccer:": "⚽️", ":soon:": "🔜",
  280. ":sos:": "🆘", ":sound:": "🔉", ":space_invader:": "👾", ":spades:": "♠️", ":spaghetti:": "🍝", ":sparkle:": "❇️",
  281. ":sparkler:": "🎇", ":sparkles:": "✨", ":sparkling_heart:": "💖", ":speak_no_evil:": "🙊", ":speaker:": "🔈",
  282. ":speech_balloon:": "💬", ":speedboat:": "🚤", ":squirrel:": "", ":star:": "⭐️", ":star2:": "🌟", ":stars:": "🌠",
  283. ":station:": "🚉", ":statue_of_liberty:": "🗽", ":steam_locomotive:": "🚂", ":stew:": "🍲", ":straight_ruler:": "📏",
  284. ":strawberry:": "🍓", ":stuck_out_tongue:": "😛", ":stuck_out_tongue_closed_eyes:": "😝",
  285. ":stuck_out_tongue_winking_eye:": "😜", ":sun_with_face:": "🌞", ":sunflower:": "🌻", ":sunglasses:": "😎",
  286. ":sunny:": "☀️", ":sunrise:": "🌅", ":sunrise_over_mountains:": "🌄", ":surfer:": "🏄", ":sushi:": "🍣",
  287. ":suspect:": "", ":suspension_railway:": "🚟", ":sweat:": "😓", ":sweat_drops:": "💦",
  288. ":sweat_smile:": "😅", ":sweet_potato:": "🍠", ":swimmer:": "🏊", ":symbols:": "🔣", ":syringe:": "💉",
  289. ":tada:": "🎉", ":tanabata_tree:": "🎋", ":tangerine:": "🍊", ":taurus:": "♉️", ":taxi:": "🚕", ":tea:": "🍵",
  290. ":telephone:": "☎️", ":telephone_receiver:": "📞", ":telescope:": "🔭", ":tennis:": "🎾", ":tent:": "⛺️",
  291. ":thought_balloon:": "💭", ":three:": "3️⃣", ":thumbsdown:": "👎", ":thumbsup:": "👍", ":ticket:": "🎫",
  292. ":tiger:": "🐯", ":tiger2:": "🐅", ":tired_face:": "😫", ":tm:": "™️", ":toilet:": "🚽", ":tokyo_tower:": "🗼",
  293. ":tomato:": "🍅", ":tongue:": "👅", ":top:": "🔝", ":tophat:": "🎩", ":tractor:": "🚜", ":traffic_light:": "🚥",
  294. ":train:": "🚋", ":train2:": "🚆", ":tram:": "🚊", ":triangular_flag_on_post:": "🚩", ":triangular_ruler:": "📐",
  295. ":trident:": "🔱", ":triumph:": "😤", ":trolleybus:": "🚎", ":trollface:": "", ":trophy:": "🏆",
  296. ":tropical_drink:": "🍹", ":tropical_fish:": "🐠", ":truck:": "🚚", ":trumpet:": "🎺", ":tshirt:": "👕",
  297. ":tulip:": "🌷", ":turtle:": "🐢", ":tv:": "📺", ":twisted_rightwards_arrows:": "🔀", ":two:": "2️⃣",
  298. ":two_hearts:": "💕", ":two_men_holding_hands:": "👬", ":two_women_holding_hands:": "👭", ":u5272:": "🈹",
  299. ":u5408:": "🈴", ":u55b6:": "🈺", ":u6307:": "🈯️", ":u6708:": "🈷️", ":u6709:": "🈶", ":u6e80:": "🈵",
  300. ":u7121:": "🈚️", ":u7533:": "🈸", ":u7981:": "🈲", ":u7a7a:": "🈳", ":uk:": "🇬🇧", ":ukraine:": "🇺🇦", ":umbrella:": "☔️",
  301. ":unamused:": "😒", ":underage:": "🔞", ":unlock:": "🔓", ":up:": "🆙", ":us:": "🇺🇸", ":us_virgin_islands:": "🇻🇮",
  302. ":v:": "✌️", ":vertical_traffic_light:": "🚦", ":vhs:": "📼", ":vibration_mode:": "📳", ":video_camera:": "📹",
  303. ":video_game:": "🎮", ":violin:": "🎻", ":virgo:": "♍️", ":volcano:": "🌋", ":vs:": "🆚", ":walking:": "🚶",
  304. ":walking_man:": "🚶", ":walking_woman:": "🚶\u200D♀", ":wallis_futuna:": "🇼🇫", ":waning_crescent_moon:": "🌘",
  305. ":waning_gibbous_moon:": "🌖", ":warning:": "⚠️", ":watch:": "⌚️", ":water_buffalo:": "🐃", ":watermelon:": "🍉",
  306. ":wave:": "👋", ":wavy_dash:": "〰️", ":waxing_crescent_moon:": "🌒", ":waxing_gibbous_moon:": "🌔", ":wc:": "🚾",
  307. ":weary:": "😩", ":wedding:": "💒", ":whale:": "🐳", ":whale2:": "🐋", ":wheel_of_dharma:": "☸️", ":wheelchair:": "♿️",
  308. ":white_check_mark:": "✅", ":white_circle:": "⚪️", ":white_flower:": "💮", ":white_large_square:": "⬜️",
  309. ":white_medium_small_square:": "◽️", ":white_medium_square:": "◻️", ":white_small_square:": "▫️", ":white_square_button:": "🔳",
  310. ":wilted_flower:": "🥀", ":wind_chime:": "🎐", ":wind_face:": "🌬", ":wine_glass:": "🍷", ":wink:": "😉", ":wolf:": "🐺",
  311. ":woman:": "👩", ":womans_clothes:": "👚", ":womans_hat:": "👒", ":womens:": "🚺", ":world_map:": "🗺", ":worried:": "😟",
  312. ":wrench:": "🔧", ":x:": "❌", ":yellow_heart:": "💛", ":yen:": "💴", ":yum:": "😋", ":zap:": "⚡️", ":zero:": "0️⃣", ":zzz:": "💤"}
  313. // Replace chunks with emojis if they exist in the dictionary, otherwise keep them unchanged
  314. const result = chunks.map(chunk => (emoji[chunk] ? emoji[chunk] : chunk));
  315. // Join the chunks to form the final string
  316. return result.join('');
  317. }
  318.  
  319. function descriptionToLines(description) {
  320. const svgEntities = {
  321. '&': '&amp;',
  322. '<': '&lt;',
  323. '>': '&gt;',
  324. '"': '&quot;',
  325. "'": '&apos;',
  326. '%': '&#37;',
  327. '{': '&#123;',
  328. '}': '&#125;',
  329. '#': '&#35;',
  330. '=': '&#61;',
  331. '(': '&#40;',
  332. ')': '&#41;',
  333. ';': '&#59;',
  334. '/': '&#47;',
  335. '?': '&#63;',
  336. '@': '&#64;',
  337. '^': '&#94;',
  338. '|': '&#124;',
  339. '~': '&#126;'
  340. };
  341. const wordRe = /[\u4e00-\u9fff]|[a-zA-Z0-9]+(?!=[\u4e00-\u9fff])|[^\u4e00-\u9fff\w\s]|\s/g;
  342. const words = description.match(wordRe);
  343. let line = "";
  344. const lines = [];
  345. let length = 0;
  346. for (const word of words) {
  347. var word_len = 0
  348. if (word.charCodeAt()>255) {
  349. word_len = 16;
  350. } else {
  351. for (var i = 0;i<word.length;i++){
  352. if (word.charCodeAt(i) >64 && word.charCodeAt(i)<91) {
  353. word_len += 10
  354. }else{
  355. word_len += 8
  356. }
  357. }
  358. }
  359. length += word_len
  360. if (length > 380) {
  361. line = line.replace(/[&<>"'%{}#=();\/?@^|~]/g, match => svgEntities[match]);
  362. lines.push(line);
  363. line = word;
  364. length = word_len;
  365. }else{
  366. line += word;
  367. }
  368. }
  369. if (line !== "") {
  370. line = line.replace(/[&<>"'%{}#=();\/?@^|~]/g, match => svgEntities[match]);
  371. lines.push(line);
  372. }
  373. return lines;
  374. }
  375.  
  376. function doCreateDescription(description_lines) {
  377. let y = 86;
  378. const diff = 21;
  379. const descript_element =
  380. '<g fill="#586069" fill-opacity="1" stroke="#586069" stroke-opacity="1" ' +
  381. 'stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" ' +
  382. 'transform="matrix(1,0,0,1,0,0)">' +
  383. '<text fill="#586069" fill-opacity="1" stroke="none" x="17" y="{y}" ' +
  384. 'font-family="sans-serif" font-size="14" font-weight="550" font-style="normal">' +
  385. '{content}</text></g>';
  386. let desc = '';
  387. for (const line of description_lines) {
  388. const e = descript_element.replace('{y}', y).replace('{content}', line);
  389. desc += e;
  390. y += diff;
  391. }
  392. return [desc, y - diff];
  393. }
  394.  
  395. function createDesc(description){
  396. var desc_with_emoji = renderEmoji(description)
  397. var desc_lines = descriptionToLines(desc_with_emoji)
  398. return doCreateDescription(desc_lines)
  399. }
  400.  
  401. function createLanguage(circle_y, language) {
  402. const language_color_dict = {"1C Enterprise": "#814CCC", "2-Dimensional Array": "#38761D", "4D": "#004289", "ABAP": "#E8274B", "ABAP CDS": "#555e25", "AGS Script": "#B9D9FF", "AIDL": "#34EB6B", "AL": "#3AA2B5", "AMPL": "#E6EFBB", "ANTLR": "#9DC3FF", "API Blueprint": "#2ACCA8", "APL": "#5A8164", "ASP.NET": "#9400ff", "ATS": "#1ac620", "ActionScript": "#882B0F", "Ada": "#02f88c", "Adblock Filter List": "#800000", "Adobe Font Metrics": "#fa0f00", "Agda": "#315665", "Alloy": "#64C800", "Alpine Abuild": "#0D597F", "Altium Designer": "#A89663", "AngelScript": "#C7D7DC", "Ant Build System": "#A9157E", "Antlers": "#ff269e", "ApacheConf": "#d12127", "Apex": "#1797c0", "Apollo Guidance Computer": "#0B3D91", "AppleScript": "#101F1F", "Arc": "#aa2afe", "AsciiDoc": "#73a0c5", "AspectJ": "#a957b0", "Assembly": "#6E4C13", "Astro": "#ff5a03", "Asymptote": "#ff0000", "Augeas": "#9CC134", "AutoHotkey": "#6594b9", "AutoIt": "#1C3552", "Avro IDL": "#0040FF", "Awk": "#c30e9b", "BASIC": "#ff0000", "Ballerina": "#FF5000", "Batchfile": "#C1F12E", "Beef": "#a52f4e", "Berry": "#15A13C", "BibTeX": "#778899", "Bicep": "#519aba", "Bikeshed": "#5562ac", "Bison": "#6A463F", "BitBake": "#00bce4", "Blade": "#f7523f", "BlitzBasic": "#00FFAE", "BlitzMax": "#cd6400", "Bluespec": "#12223c", "Boo": "#d4bec1", "Boogie": "#c80fa0", "Brainfuck": "#2F2530", "BrighterScript": "#66AABB", "Brightscript": "#662D91", "Browserslist": "#ffd539", "C": "#555555", "C#": "#178600", "C++": "#f34b7d", "CAP CDS": "#0092d1", "CLIPS": "#00A300", "CMake": "#DA3434", "COLLADA": "#F1A42B", "CSON": "#244776", "CSS": "#563d7c", "CSV": "#237346", "CUE": "#5886E1", "CWeb": "#00007a", "Cabal Config": "#483465", "Cadence": "#00ef8b", "Cairo": "#ff4a48", "CameLIGO": "#3be133", "Cap'n Proto": "#c42727", "Ceylon": "#dfa535", "Chapel": "#8dc63f", "ChucK": "#3f8000", "Circom": "#707575", "Cirru": "#ccccff", "Clarion": "#db901e", "Clarity": "#5546ff", "Classic ASP": "#6a40fd", "Clean": "#3F85AF", "Click": "#E4E6F3", "Clojure": "#db5855", "Closure Templates": "#0d948f", "Cloud Firestore Security Rules": "#FFA000", "CodeQL": "#140f46", "CoffeeScript": "#244776", "ColdFusion": "#ed2cd6", "ColdFusion CFC": "#ed2cd6", "Common Lisp": "#3fb68b", "Common Workflow Language": "#B5314C", "Component Pascal": "#B0CE4E", "Coq": "#d0b68c", "Crystal": "#000100", "Csound": "#1a1a1a", "Csound Document": "#1a1a1a", "Csound Score": "#1a1a1a", "Cuda": "#3A4E3A", "Curry": "#531242", "Cypher": "#34c0eb", "Cython": "#fedf5b", "D": "#ba595e", "D2": "#526ee8", "DM": "#447265", "Dafny": "#FFEC25", "Darcs Patch": "#8eff23", "Dart": "#00B4AB", "DataWeave": "#003a52", "Debian Package Control File": "#D70751", "DenizenScript": "#FBEE96", "Dhall": "#dfafff", "DirectX 3D File": "#aace60", "Dockerfile": "#384d54", "Dogescript": "#cca760", "Dotenv": "#e5d559", "Dylan": "#6c616e", "E": "#ccce35", "ECL": "#8a1267", "ECLiPSe": "#001d9d", "EJS": "#a91e50", "EQ": "#a78649", "Earthly": "#2af0ff", "Easybuild": "#069406", "Ecere Projects": "#913960", "Ecmarkup": "#eb8131", "EditorConfig": "#fff1f2", "Eiffel": "#4d6977", "Elixir": "#6e4a7e", "Elm": "#60B5CC", "Elvish": "#55BB55", "Elvish Transcript": "#55BB55", "Emacs Lisp": "#c065db", "EmberScript": "#FFF4F3", "Erlang": "#B83998", "Euphoria": "#FF790B", "F#": "#b845fc", "F*": "#572e30", "FIGlet Font": "#FFDDBB", "FLUX": "#88ccff", "Factor": "#636746", "Fancy": "#7b9db4", "Fantom": "#14253c", "Faust": "#c37240", "Fennel": "#fff3d7", "Filebench WML": "#F6B900", "Fluent": "#ffcc33", "Forth": "#341708", "Fortran": "#4d41b1", "Fortran Free Form": "#4d41b1", "FreeBasic": "#141AC9", "FreeMarker": "#0050b2", "Frege": "#00cafe", "Futhark": "#5f021f", "G-code": "#D08CF2", "GAML": "#FFC766", "GAMS": "#f49a22", "GAP": "#0000cc", "GCC Machine Description": "#FFCFAB", "GDScript": "#355570", "GEDCOM": "#003058", "GLSL": "#5686a5", "GSC": "#FF6800", "Game Maker Language": "#71b417", "Gemfile.lock": "#701516", "Gemini": "#ff6900", "Genero": "#63408e", "Genero Forms": "#d8df39", "Genie": "#fb855d", "Genshi": "#951531", "Gentoo Ebuild": "#9400ff", "Gentoo Eclass": "#9400ff", "Gerber Image": "#d20b00", "Gherkin": "#5B2063", "Git Attributes": "#F44D27", "Git Config": "#F44D27", "Git Revision List": "#F44D27", "Gleam": "#ffaff3", "Glyph": "#c1ac7f", "Gnuplot": "#f0a9f0", "Go": "#00ADD8", "Go Checksums": "#00ADD8", "Go Module": "#00ADD8", "Go Workspace": "#00ADD8", "Godot Resource": "#355570", "Golo": "#88562A", "Gosu": "#82937f", "Grace": "#615f8b", "Gradle": "#02303a", "Grammatical Framework": "#ff0000", "GraphQL": "#e10098", "Graphviz (DOT)": "#2596be", "Groovy": "#4298b8", "Groovy Server Pages": "#4298b8", "HAProxy": "#106da9", "HCL": "#844FBA", "HLSL": "#aace60", "HOCON": "#9ff8ee", "HTML": "#e34c26", "HTML+ECR": "#2e1052", "HTML+EEX": "#6e4a7e", "HTML+ERB": "#701516", "HTML+PHP": "#4f5d95", "HTML+Razor": "#512be4", "HTTP": "#005C9C", "HXML": "#f68712", "Hack": "#878787", "Haml": "#ece2a9", "Handlebars": "#f7931e", "Harbour": "#0e60e3", "Haskell": "#5e5086", "Haxe": "#df7900", "HiveQL": "#dce200", "HolyC": "#ffefaf", "Hosts File": "#308888", "Hy": "#7790B2", "IDL": "#a3522f", "IGOR Pro": "#0000cc", "INI": "#d1dbe0", "Idris": "#b30000", "Ignore List": "#000000", "ImageJ Macro": "#99AAFF", "Imba": "#16cec6", "Inno Setup": "#264b99", "Io": "#a9188d", "Ioke": "#078193", "Isabelle": "#FEFE00", "Isabelle ROOT": "#FEFE00", "J": "#9EEDFF", "JAR Manifest": "#b07219", "JCL": "#d90e09", "JFlex": "#DBCA00", "JSON": "#292929", "JSON with Comments": "#292929", "JSON5": "#267CB9", "JSONLD": "#0c479c", "JSONiq": "#40d47e", "Janet": "#0886a5", "Jasmin": "#d03600", "Java": "#b07219", "Java Properties": "#2A6277", "Java Server Pages": "#2A6277", "JavaScript": "#f1e05a", "JavaScript+ERB": "#f1e05a", "Jest Snapshot": "#15c213", "JetBrains MPS": "#21D789", "Jinja": "#a52a22", "Jison": "#56b3cb", "Jison Lex": "#56b3cb", "Jolie": "#843179", "Jsonnet": "#0064bd", "Julia": "#a270ba", "Jupyter Notebook": "#DA5B0B", "Just": "#384d54", "KRL": "#28430A", "Kaitai Struct": "#773b37", "KakouneScript": "#6f8042", "KerboScript": "#41adf0", "KiCad Layout": "#2f4aab", "KiCad Legacy Layout": "#2f4aab", "KiCad Schematic": "#2f4aab", "Kotlin": "#A97BFF", "LFE": "#4C3023", "LLVM": "#185619", "LOLCODE": "#cc9900", "LSL": "#3d9970", "LabVIEW": "#fede06", "Lark": "#2980B9", "Lasso": "#999999", "Latte": "#f2a542", "Less": "#1d365d", "Lex": "#DBCA00", "LigoLANG": "#0e74ff", "LilyPond": "#9ccc7c", "Liquid": "#67b8de", "Literate Agda": "#315665", "Literate CoffeeScript": "#244776", "Literate Haskell": "#5e5086", "LiveScript": "#499886", "Logtalk": "#295b9a", "LookML": "#652B81", "Lua": "#000080", "MATLAB": "#e16737", "MAXScript": "#00a6a6", "MDX": "#fcb32c", "MLIR": "#5EC8DB", "MQL4": "#62A8D6", "MQL5": "#4A76B8", "MTML": "#b7e1f4", "Macaulay2": "#d8ffff", "Makefile": "#427819", "Mako": "#7e858d", "Markdown": "#083fa1", "Marko": "#42bff2", "Mask": "#f97732", "Mathematica": "#dd1100", "Max": "#c4a79c", "Mercury": "#ff2b2b", "Mermaid": "#ff3670", "Meson": "#007800", "Metal": "#8f14e9", "MiniYAML": "#ff1111", "Mint": "#02b046", "Mirah": "#c7a938", "Modelica": "#de1d31", "Modula-2": "#10253f", "Modula-3": "#223388", "Monkey C": "#8D6747", "MoonScript": "#ff4585", "Motoko": "#fbb03b", "Motorola 68K Assembly": "#005daa", "Move": "#4a137a", "Mustache": "#724b3b", "NCL": "#28431f", "NPM Config": "#cb3837", "NWScript": "#111522", "Nasal": "#1d2c4e", "Nearley": "#990000", "Nemerle": "#3d3c6e", "NetLinx": "#0aa0ff", "NetLinx+ERB": "#747faa", "NetLogo": "#ff6375", "NewLisp": "#87AED7", "Nextflow": "#3ac486", "Nginx": "#009639", "Nim": "#ffc200", "Nit": "#009917", "Nix": "#7e7eff", "Nu": "#c9df40", "NumPy": "#9C8AF9", "Nunjucks": "#3d8137", "Nushell": "#4E9906", "OASv2-json": "#85ea2d", "OASv2-yaml": "#85ea2d", "OASv3-json": "#85ea2d", "OASv3-yaml": "#85ea2d", "OCaml": "#ef7a08", "ObjectScript": "#424893", "Objective-C": "#438eff", "Objective-C++": "#6866fb", "Objective-J": "#ff0c5a", "Odin": "#60AFFE", "Omgrofl": "#cabbff", "Opal": "#f7ede0", "Open Policy Agent": "#7d9199", "OpenAPI Specification v2": "#85ea2d", "OpenAPI Specification v3": "#85ea2d", "OpenCL": "#ed2e2d", "OpenEdge ABL": "#5ce600", "OpenQASM": "#AA70FF", "OpenSCAD": "#e5cd45", "Option List": "#476732", "Org": "#77aa99", "Oxygene": "#cdd0e3", "Oz": "#fab738", "P4": "#7055b5", "PDDL": "#0d00ff", "PEG.js": "#234d6b", "PHP": "#4F5D95", "PLSQL": "#dad8d8", "PLpgSQL": "#336790", "POV-Ray SDL": "#6bac65", "Pact": "#F7A8B8", "Pan": "#cc0000", "Papyrus": "#6600cc", "Parrot": "#f3ca0a", "Pascal": "#E3F171", "Pawn": "#dbb284", "Pep8": "#C76F5B", "Perl": "#0298c3", "PicoLisp": "#6067af", "PigLatin": "#fcd7de", "Pike": "#005390", "PlantUML": "#fbbd16", "PogoScript": "#d80074", "Polar": "#ae81ff", "Portugol": "#f8bd00", "PostCSS": "#dc3a0c", "PostScript": "#da291c", "PowerBuilder": "#8f0f8d", "PowerShell": "#012456", "Prisma": "#0c344b", "Processing": "#0096D8", "Procfile": "#3B2F63", "Prolog": "#74283c", "Promela": "#de0000", "Propeller Spin": "#7fa2a7", "Pug": "#a86454", "Puppet": "#302B6D", "PureBasic": "#5a6986", "PureScript": "#1D222D", "Pyret": "#ee1e10", "Python": "#3572A5", "Python console": "#3572A5", "Python traceback": "#3572A5", "Q#": "#fed659", "QML": "#44a51c", "Qt Script": "#00b841", "Quake": "#882233", "R": "#198CE7", "RAML": "#77d9fb", "RBS": "#701516", "RDoc": "#701516", "REXX": "#d90e09", "RMarkdown": "#198ce7", "RPGLE": "#2BDE21", "RUNOFF": "#665a4e", "Racket": "#3c5caa", "Ragel": "#9d5200", "Raku": "#0000fb", "Rascal": "#fffaa0", "ReScript": "#ed5051", "Reason": "#ff5847", "ReasonLIGO": "#ff5847", "Rebol": "#358a5b", "Record Jar": "#0673ba", "Red": "#f50000", "Regular Expression": "#009a00", "Ren'Py": "#ff7f7f", "Ring": "#2D54CB", "Riot": "#A71E49", "RobotFramework": "#00c0b5", "Roff": "#ecdebe", "Roff Manpage": "#ecdebe", "Rouge": "#cc0088", "RouterOS Script": "#DE3941", "Ruby": "#701516", "Rust": "#dea584", "SAS": "#B34936", "SCSS": "#c6538c", "SPARQL": "#0C4597", "SQF": "#3F3F3F", "SQL": "#e38c00", "SQLPL": "#e38c00", "SRecode Template": "#348a34", "STL": "#373b5e", "SVG": "#ff9900", "SaltStack": "#646464", "Sass": "#a53b70", "Scala": "#c22d40", "Scaml": "#bd181a", "Scenic": "#fdc700", "Scheme": "#1e4aec", "Scilab": "#ca0f21", "Self": "#0579aa", "ShaderLab": "#222c37", "Shell": "#89e051", "ShellCheck Config": "#cecfcb", "Shen": "#120F14", "Simple File Verification": "#C9BFED", "Singularity": "#64E6AD", "Slash": "#007eff", "Slice": "#003fa2", "Slim": "#2b2b2b", "SmPL": "#c94949", "Smalltalk": "#596706", "Smarty": "#f0c040", "Smithy": "#c44536", "Snakemake": "#419179", "Solidity": "#AA6746", "SourcePawn": "#f69e1d", "Squirrel": "#800000", "Stan": "#b2011d", "Standard ML": "#dc566d", "Starlark": "#76d275", "Stata": "#1a5f91", "StringTemplate": "#3fb34f", "Stylus": "#ff6347", "SubRip Text": "#9e0101", "SugarSS": "#2fcc9f", "SuperCollider": "#46390b", "Svelte": "#ff3e00", "Sway": "#dea584", "Swift": "#F05138", "SystemVerilog": "#DAE1C2", "TI Program": "#A0AA87", "TL-Verilog": "#C40023", "TLA": "#4b0079", "TOML": "#9c4221", "TSQL": "#e38c00", "TSV": "#237346", "TSX": "#3178c6", "TXL": "#0178b8", "Talon": "#333333", "Tcl": "#e4cc98", "TeX": "#3D6117", "Terra": "#00004c", "TextMate Properties": "#df66e4", "Textile": "#ffe7ac", "Thrift": "#D12127", "Turing": "#cf142b", "Twig": "#c1d026", "TypeScript": "#3178c6", "Unified Parallel C": "#4e3617", "Unity3D Asset": "#222c37", "Uno": "#9933cc", "UnrealScript": "#a54c4d", "UrWeb": "#ccccee", "V": "#4f87c4", "VBA": "#867db1", "VBScript": "#15dcdc", "VCL": "#148AA8", "VHDL": "#adb2cb", "Vala": "#a56de2", "Valve Data Format": "#f26025", "Velocity Template Language": "#507cff", "Verilog": "#b2b7f8", "Vim Help File": "#199f4b", "Vim Script": "#199f4b", "Vim Snippet": "#199f4b", "Visual Basic .NET": "#945db7", "Visual Basic 6.0": "#2c6353", "Volt": "#1F1F1F", "Vue": "#41b883", "Vyper": "#2980b9", "WDL": "#42f1f4", "WGSL": "#1a5e9a", "Web Ontology Language": "#5b70bd", "WebAssembly": "#04133b", "WebAssembly Interface Type": "#6250e7", "Whiley": "#d5c397", "Wikitext": "#fc5757", "Windows Registry Entries": "#52d5ff", "Witcher Script": "#ff0000", "Wollok": "#a23738", "World of Warcraft Addon Data": "#f7e43f", "Wren": "#383838", "X10": "#4B6BEF", "XC": "#99DA07", "XML": "#0060ac", "XML Property List": "#0060ac", "XQuery": "#5232e7", "XSLT": "#EB8CEB", "Xojo": "#81bd41", "Xonsh": "#285EEF", "Xtend": "#24255d", "YAML": "#cb171e", "YARA": "#220000", "YASnippet": "#32AB90", "Yacc": "#4B6C4B", "Yul": "#794932", "ZAP": "#0d665e", "ZIL": "#dc75e5", "ZenScript": "#00BCD1", "Zephir": "#118f9e", "Zig": "#ec915c", "Zimpl": "#d67711", "eC": "#913960", "fish": "#4aae47", "hoon": "#00b171", "jq": "#c7254e", "kvlang": "#1da6e0", "mIRC Script": "#3d57c3", "mcfunction": "#E22837", "mupad": "#244963", "nanorc": "#2d004d", "nesC": "#94B0C7", "ooc": "#b0b77e", "q": "#0040cd", "reStructuredText": "#141414", "sed": "#64b970", "wisp": "#7582D1", "xBase": "#403a40"}
  403. const language_format =
  404. '<circle cx="25" cy="{circle_y}" r="7" stroke="none" fill="{color}"></circle>' +
  405. '<g transform="matrix(1,0,0,1,0,0)">' +
  406. '<text fill="#24292e" fill-opacity="1" stroke="none" x="{language_x}" y="{language_y}" font-family="sans-serif" ' +
  407. 'font-size="12" font-weight="400" font-style="normal">{language}</text>' +
  408. '</g>';
  409. const language_x = 35;
  410. const language_y = circle_y + 4;
  411. let color, en_count = 0, cn_count = 0;
  412. if (!language) {
  413. language = 'None';
  414. color = '#000000';
  415. } else {
  416. color = language_color_dict[language] || '#000000';
  417. }
  418. const en_char_len = 8;
  419. const cn_char_len = 16;
  420. for (const char of language) {
  421. if ('\u4e00' <= char && char <= '\u9fff') {
  422. cn_count += 1;
  423. } else {
  424. en_count += 1;
  425. }
  426. }
  427. const next_x = cn_count * cn_char_len + en_count * en_char_len + language_x;
  428. return [language_format.replace('{circle_y}', circle_y)
  429. .replace('{language_x}', language_x)
  430. .replace('{language_y}', language_y)
  431. .replace('{color}', color)
  432. .replace('{language}', language), next_x];
  433. }
  434.  
  435. // 通过GM_xmlhttpRequest获取PNG图片的二进制数据
  436. function getBinaryDataFromURL(url) {
  437. return new Promise((resolve, reject) => {
  438. GM_xmlhttpRequest({
  439. method: "GET",
  440. url: url,
  441. responseType: "arraybuffer",
  442. onload: function(response) {
  443. const binaryData = response.response;
  444. resolve(binaryData);
  445. },
  446. onerror: function(error) {
  447. console.error("Error fetching the image:", error);
  448. reject(error);
  449. }
  450. });
  451. });
  452. }
  453.  
  454. // 将二进制数据转换为base64编码
  455. function convertBinaryToBase64(binaryData) {
  456. return new Promise((resolve, reject) => {
  457. const reader = new FileReader();
  458. reader.onloadend = function() {
  459. const base64Value = reader.result.split(",")[1];
  460. resolve(base64Value);
  461. };
  462. reader.readAsDataURL(new Blob([binaryData], { type: "image/png" }));
  463. });
  464. }
  465.  
  466. // 在这里调用获取二进制数据和转换为base64的函数
  467. async function processImage(imageUrl) {
  468. try {
  469. const binaryData = await getBinaryDataFromURL(imageUrl);
  470. const base64Value = await convertBinaryToBase64(binaryData);
  471. return base64Value;
  472. } catch (error) {
  473. console.error("Failed to process the image:", error);
  474. return null;
  475. }
  476. }
  477.  
  478. function startDownload(svgContent, fileName) {
  479. // 将SVG内容转换为Blob对象
  480. const blob = new Blob([svgContent], { type: 'image/svg+xml' });
  481.  
  482. // 创建下载链接
  483. const downloadLink = document.createElement("a");
  484. downloadLink.href = URL.createObjectURL(blob);
  485. downloadLink.download = fileName; // 下载文件的名称
  486.  
  487. // 触发点击事件,弹出下载框
  488. downloadLink.dispatchEvent(new MouseEvent('click'));
  489.  
  490. // 释放URL对象,防止内存泄漏
  491. URL.revokeObjectURL(downloadLink.href);
  492. }
  493.  
  494. async function getCard() {
  495. var repo = getRepoName()
  496. var info_msg = await getFromAPI(repo.url(), 'json')
  497. var gitInfo = new GithubInfo(info_msg)
  498. try {
  499. const response = await fetch(info_msg.tags_url);
  500. const data = await response.json();
  501. gitInfo.tag_count = String(data.length);
  502. } catch (error) {
  503. console.error("请求出错:", error);
  504. throw error; // 在此抛出错误,以确保调用函数的地方可以捕获到错误
  505. }
  506. console.log(gitInfo)
  507.  
  508. //构建repo
  509. var repo_href = gitInfo.repo_href
  510. var repo_name = gitInfo.repo_name
  511. const repo_part = `
  512. <g fill="#586069" fill-opacity="1" stroke="none" transform="matrix(1.25,0,0,1.25,18,18)">
  513. <path vector-effect="none" fill-rule="evenodd" d="M4,9 L3,9 L3,8 L4,8 L4,9 M4,6 L3,6 L3,7 L4,7 L4,6 M4,4 L3,4 L3,5 L4,5 L4,4 M4,2 L3,2 L3,3 L4,3 L4,2 M12,1 L12,13 C12,13.55 11.55,14 11,14 L6,14 L6,16 L4.5,14.5 L3,16 L3,14 L1,14 C0.45,14 0,13.55 0,13 L0,1 C0,0.45 0.45,0 1,0 L11,0 C11.55,0 12,0.45 12,1 M11,11 L1,11 L1,13 L3,13 L3,12 L6,12 L6,13 L11,13 L11,11 M11,1 L2,1 L2,10 L11,10 L11,1"></path>
  514. </g>
  515. <g fill="#0366d6" fill-opacity="1" stroke="#0366d6" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,25,0)">
  516. <a target="_blank" href="${repo_href}">
  517. <text fill="#0366d6" fill-opacity="1" stroke="none" xml:space="preserve" x="17" y="33" font-family="sans-serif" font-size="18" font-weight="630" font-style="normal">${repo_name}</text>
  518. </a>
  519. </g>
  520. `;
  521. //构建owner
  522. var owner_href = gitInfo.owner.html_url
  523. //var img = gitInfo.owner.avatar_url
  524. var img = await processImage(gitInfo.owner.avatar_url)
  525. var owner = gitInfo.owner.login
  526. // const base64Value = await processImage(gitInfo.owner.avatar_url);
  527. // console.log("PNG图片的base64值:", base64Value);
  528. const owner_part = `
  529. <g transform="matrix(1,0,0,1,0,0)">
  530. <a target="_blank" href="${owner_href}">
  531. <circle cx="25" cy="56" r="12" stroke="#afb8c1" stroke-width="1.5" fill="none" />
  532. <image stroke="null" id="svg_1" height="24" width="24" x="13" y="44" clip-path="url(#circleClip)" href="data:image/png;base64,${img}"/>
  533. </a>
  534. </g>
  535. <g transform="matrix(1,0,0,1,25,0)">
  536. <a target="_blank" href="${owner_href}">
  537. <text fill="#000000" fill-opacity="1" stroke="none" xml:space="preserve" x="17" y="59.5" font-family="sans-serif" font-size="15" font-weight="540" font-style="normal">${owner}</text>
  538. </a>
  539. </g>
  540. `;
  541.  
  542. //构建description
  543. var desc_result = createDesc(gitInfo.description)
  544. var desc_part = desc_result[0]
  545. var desc_last_y = desc_result[1]
  546. var language_y = desc_last_y + 18
  547. var next_y = desc_last_y + 10
  548.  
  549. //构建language部分
  550. var language_result = createLanguage(language_y,gitInfo.language)
  551. var language_part = language_result[0]
  552. var next_x = language_result[1]
  553.  
  554. //构建各个info部分
  555. var icon_x = next_x + 16
  556. var icon_y = next_y
  557. var href = gitInfo.star_href
  558. var info_x = icon_x + 21
  559. var info_y = icon_y + 12
  560. var info = gitInfo.stars_count
  561. const star_info = `
  562. <g transform="matrix(1,0,0,1,${icon_x},${icon_y})">
  563. <a target="_blank" href="${href}">
  564. <path fill="#656d76" stroke="none" d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
  565. </a>
  566. </g>
  567. <g transform="matrix(1,0,0,1,0,0)">
  568. <a target="_blank" href="${href}">
  569. <text fill="#656d76" fill-opacity="1" stroke="none" x="${info_x}" y="${info_y}" font-family="sans-serif"
  570. font-size="12" font-weight="400" font-style="normal">${info}</text>
  571. </a>
  572. </g>
  573. `
  574. icon_x = info_x + 8*info.length + 16
  575. href = gitInfo.fork_href
  576. info_x = icon_x +21
  577. info = gitInfo.forks_count
  578. const fork_info = `
  579. <g transform="matrix(1,0,0,1,${icon_x},${icon_y})">
  580. <a target="_blank" href="${href}">
  581. <path fill="#656d76" stroke="none" d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>
  582. </a>
  583. </g>
  584. <g transform="matrix(1,0,0,1,0,0)">
  585. <a target="_blank" href="${href}">
  586. <text fill="#656d76" fill-opacity="1" stroke="none" x="${info_x}" y="${info_y}" font-family="sans-serif"
  587. font-size="12" font-weight="400" font-style="normal">${info}</text>
  588. </a>
  589. </g>
  590. `
  591. icon_x = info_x + 8*info.length + 16
  592. href = gitInfo.tag_href
  593. info_x = icon_x +21
  594. info = gitInfo.tag_count
  595. const tag_info = `
  596. <g transform="matrix(1,0,0,1,${icon_x},${icon_y})">
  597. <a target="_blank" href="${href}">
  598. <path fill="#656d76" stroke="none" d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path>
  599. </a>
  600. </g>
  601. <g transform="matrix(1,0,0,1,0,0)">
  602. <a target="_blank" href="${href}">
  603. <text fill="#656d76" fill-opacity="1" stroke="none" x="${info_x}" y="${info_y}" font-family="sans-serif"
  604. font-size="12" font-weight="400" font-style="normal">${info}</text>
  605. </a>
  606. </g>
  607. `
  608. let license_info = ''
  609. if (gitInfo.license !==undefined){
  610. icon_x = info_x + 8*info.length + 16
  611. href = gitInfo.license_href
  612. info_x = icon_x +21
  613. info = gitInfo.license
  614. license_info = `
  615. <g transform="matrix(1,0,0,1,${icon_x},${icon_y})">
  616. <a target="_blank" href="${href}">
  617. <path fill="#656d76" stroke="none" d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path>
  618. </a>
  619. </g>
  620. <g transform="matrix(1,0,0,1,0,0)">
  621. <a target="_blank" href="${href}">
  622. <text fill="#656d76" fill-opacity="1" stroke="none" x="${info_x}" y="${info_y}" font-family="sans-serif"
  623. font-size="12" font-weight="400" font-style="normal">${info}</text>
  624. </a>
  625. </g>
  626. `
  627. }
  628. var height = desc_last_y+33
  629. var body = repo_part + owner_part + desc_part + language_part + star_info + fork_info + tag_info + license_info
  630. const svg = `
  631. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="422" height="${height}" version="1.2" baseProfile="tiny" data-reactroot="">
  632. <defs>
  633. <clipPath id="circleClip">
  634. <circle cx="25" cy="56" r="12" />
  635. </clipPath>
  636. </defs>
  637. <g fill="none" stroke="black" stroke-width="1" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="bevel">
  638. <g fill="#ffffff" fill-opacity="1" stroke="none" transform="matrix(1,0,0,1,0,0)">
  639. <rect x="0" y="0" width="420" height="${height}"></rect>
  640. </g>
  641. <rect x="0" y="0" width="421" height="${height}" stroke="#eaecef" stroke-width="2"></rect>
  642. <g transform="matrix(1,0,0,1,0,-3)">${body}</g>
  643. </g>
  644. </svg>
  645. `;
  646. var file_name = repo.ownerName + '_' + repo.repoName + '.svg'
  647. startDownload(svg,file_name)
  648.  
  649. }
  650.  
  651. //在页面设置按钮
  652. var button = document.createElement("button");
  653. button.textContent = "Get\nCard"; // 竖向显示内容,使用换行符分隔
  654. button.style.borderRadius = '5px';
  655. button.style.position = "fixed";
  656. button.style.left = "-40px"; // 初始时隐藏按钮部分
  657. button.style.top = "50%";
  658. button.style.backgroundColor = '#216e39';
  659. button.style.color = 'white';
  660. button.style.border = 'none';
  661. button.style.transform = "translateY(-50%)"; // 竖向显示,并旋转90度
  662. button.style.width = "50px"; // 调整按钮宽度
  663. button.style.height = "40px"; // 调整按钮高度
  664. button.style.textAlign = "center"; // 内容居中
  665. button.style.lineHeight = "1"; // 行高,可根据需要调整
  666. button.style.zIndex = "9999";
  667. button.style.transition = "left 0.3s"; // 添加过渡效果
  668.  
  669. // 将按钮添加到页面
  670. document.body.appendChild(button);
  671.  
  672. // 绑定按钮的点击事件,点击时执行 getCard 函数
  673. button.addEventListener("click", getCard);
  674.  
  675. // 鼠标移动到按钮旁边时显示全部按钮
  676. button.addEventListener("mouseover", function () {
  677. button.style.left = "0";
  678. });
  679.  
  680. // 鼠标移出按钮时恢复部分隐藏
  681. button.addEventListener("mouseout", function () {
  682. button.style.left = "-40px";
  683. });
  684.  
  685. })();