iconify.js 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623
  1. /**
  2. * (c) Iconify
  3. *
  4. * For the full copyright and license information, please view the license.txt or license.gpl.txt
  5. * files at https://github.com/iconify/iconify
  6. *
  7. * Licensed under MIT.
  8. *
  9. * @license MIT
  10. * @version 3.1.0
  11. */
  12. var Iconify = (function (exports) {
  13. 'use strict';
  14. var defaultIconDimensions = Object.freeze(
  15. {
  16. left: 0,
  17. top: 0,
  18. width: 16,
  19. height: 16
  20. }
  21. );
  22. var defaultIconTransformations = Object.freeze({
  23. rotate: 0,
  24. vFlip: false,
  25. hFlip: false
  26. });
  27. var defaultIconProps = Object.freeze(Object.assign({}, defaultIconDimensions,
  28. defaultIconTransformations));
  29. var defaultExtendedIconProps = Object.freeze(Object.assign({}, defaultIconProps,
  30. {body: "",
  31. hidden: false}));
  32. function mergeIconTransformations(obj1, obj2) {
  33. var result = {};
  34. if (!obj1.hFlip !== !obj2.hFlip) {
  35. result.hFlip = true;
  36. }
  37. if (!obj1.vFlip !== !obj2.vFlip) {
  38. result.vFlip = true;
  39. }
  40. var rotate = ((obj1.rotate || 0) + (obj2.rotate || 0)) % 4;
  41. if (rotate) {
  42. result.rotate = rotate;
  43. }
  44. return result;
  45. }
  46. function mergeIconData(parent, child) {
  47. var result = mergeIconTransformations(parent, child);
  48. for (var key in defaultExtendedIconProps) {
  49. if (key in defaultIconTransformations) {
  50. if (key in parent && !(key in result)) {
  51. result[key] = defaultIconTransformations[key];
  52. }
  53. } else if (key in child) {
  54. result[key] = child[key];
  55. } else if (key in parent) {
  56. result[key] = parent[key];
  57. }
  58. }
  59. return result;
  60. }
  61. function getIconsTree(data, names) {
  62. var icons = data.icons;
  63. var aliases = data.aliases || /* @__PURE__ */ Object.create(null);
  64. var resolved = /* @__PURE__ */ Object.create(null);
  65. function resolve(name) {
  66. if (icons[name]) {
  67. return resolved[name] = [];
  68. }
  69. if (!(name in resolved)) {
  70. resolved[name] = null;
  71. var parent = aliases[name] && aliases[name].parent;
  72. var value = parent && resolve(parent);
  73. if (value) {
  74. resolved[name] = [parent].concat(value);
  75. }
  76. }
  77. return resolved[name];
  78. }
  79. (names || Object.keys(icons).concat(Object.keys(aliases))).forEach(resolve);
  80. return resolved;
  81. }
  82. function internalGetIconData(data, name, tree) {
  83. var icons = data.icons;
  84. var aliases = data.aliases || /* @__PURE__ */ Object.create(null);
  85. var currentProps = {};
  86. function parse(name2) {
  87. currentProps = mergeIconData(
  88. icons[name2] || aliases[name2],
  89. currentProps
  90. );
  91. }
  92. parse(name);
  93. tree.forEach(parse);
  94. return mergeIconData(data, currentProps);
  95. }
  96. function parseIconSet(data, callback) {
  97. var names = [];
  98. if (typeof data !== "object" || typeof data.icons !== "object") {
  99. return names;
  100. }
  101. if (data.not_found instanceof Array) {
  102. data.not_found.forEach(function (name) {
  103. callback(name, null);
  104. names.push(name);
  105. });
  106. }
  107. var tree = getIconsTree(data);
  108. for (var name in tree) {
  109. var item = tree[name];
  110. if (item) {
  111. callback(name, internalGetIconData(data, name, item));
  112. names.push(name);
  113. }
  114. }
  115. return names;
  116. }
  117. var matchIconName = /^[a-z0-9]+(-[a-z0-9]+)*$/;
  118. var stringToIcon = function (value, validate, allowSimpleName, provider) {
  119. if ( provider === void 0 ) provider = "";
  120. var colonSeparated = value.split(":");
  121. if (value.slice(0, 1) === "@") {
  122. if (colonSeparated.length < 2 || colonSeparated.length > 3) {
  123. return null;
  124. }
  125. provider = colonSeparated.shift().slice(1);
  126. }
  127. if (colonSeparated.length > 3 || !colonSeparated.length) {
  128. return null;
  129. }
  130. if (colonSeparated.length > 1) {
  131. var name2 = colonSeparated.pop();
  132. var prefix = colonSeparated.pop();
  133. var result = {
  134. provider: colonSeparated.length > 0 ? colonSeparated[0] : provider,
  135. prefix: prefix,
  136. name: name2
  137. };
  138. return validate && !validateIconName(result) ? null : result;
  139. }
  140. var name = colonSeparated[0];
  141. var dashSeparated = name.split("-");
  142. if (dashSeparated.length > 1) {
  143. var result$1 = {
  144. provider: provider,
  145. prefix: dashSeparated.shift(),
  146. name: dashSeparated.join("-")
  147. };
  148. return validate && !validateIconName(result$1) ? null : result$1;
  149. }
  150. if (allowSimpleName && provider === "") {
  151. var result$2 = {
  152. provider: provider,
  153. prefix: "",
  154. name: name
  155. };
  156. return validate && !validateIconName(result$2, allowSimpleName) ? null : result$2;
  157. }
  158. return null;
  159. };
  160. var validateIconName = function (icon, allowSimpleName) {
  161. if (!icon) {
  162. return false;
  163. }
  164. return !!((icon.provider === "" || icon.provider.match(matchIconName)) && (allowSimpleName && icon.prefix === "" || icon.prefix.match(matchIconName)) && icon.name.match(matchIconName));
  165. };
  166. var optionalPropertyDefaults = Object.assign({}, {provider: "",
  167. aliases: {},
  168. not_found: {}},
  169. defaultIconDimensions);
  170. function checkOptionalProps(item, defaults) {
  171. for (var prop in defaults) {
  172. if (prop in item && typeof item[prop] !== typeof defaults[prop]) {
  173. return false;
  174. }
  175. }
  176. return true;
  177. }
  178. function quicklyValidateIconSet(obj) {
  179. if (typeof obj !== "object" || obj === null) {
  180. return null;
  181. }
  182. var data = obj;
  183. if (typeof data.prefix !== "string" || !obj.icons || typeof obj.icons !== "object") {
  184. return null;
  185. }
  186. if (!checkOptionalProps(obj, optionalPropertyDefaults)) {
  187. return null;
  188. }
  189. var icons = data.icons;
  190. for (var name in icons) {
  191. var icon = icons[name];
  192. if (!name.match(matchIconName) || typeof icon.body !== "string" || !checkOptionalProps(
  193. icon,
  194. defaultExtendedIconProps
  195. )) {
  196. return null;
  197. }
  198. }
  199. var aliases = data.aliases || /* @__PURE__ */ Object.create(null);
  200. for (var name$1 in aliases) {
  201. var icon$1 = aliases[name$1];
  202. var parent = icon$1.parent;
  203. if (!name$1.match(matchIconName) || typeof parent !== "string" || !icons[parent] && !aliases[parent] || !checkOptionalProps(
  204. icon$1,
  205. defaultExtendedIconProps
  206. )) {
  207. return null;
  208. }
  209. }
  210. return data;
  211. }
  212. var dataStorage = /* @__PURE__ */ Object.create(null);
  213. function newStorage(provider, prefix) {
  214. return {
  215. provider: provider,
  216. prefix: prefix,
  217. icons: /* @__PURE__ */ Object.create(null),
  218. missing: /* @__PURE__ */ new Set()
  219. };
  220. }
  221. function getStorage(provider, prefix) {
  222. var providerStorage = dataStorage[provider] || (dataStorage[provider] = /* @__PURE__ */ Object.create(null));
  223. return providerStorage[prefix] || (providerStorage[prefix] = newStorage(provider, prefix));
  224. }
  225. function addIconSet(storage, data) {
  226. if (!quicklyValidateIconSet(data)) {
  227. return [];
  228. }
  229. return parseIconSet(data, function (name, icon) {
  230. if (icon) {
  231. storage.icons[name] = icon;
  232. } else {
  233. storage.missing.add(name);
  234. }
  235. });
  236. }
  237. function addIconToStorage(storage, name, icon) {
  238. try {
  239. if (typeof icon.body === "string") {
  240. storage.icons[name] = Object.assign({}, icon);
  241. return true;
  242. }
  243. } catch (err) {
  244. }
  245. return false;
  246. }
  247. function listIcons(provider, prefix) {
  248. var allIcons = [];
  249. var providers = typeof provider === "string" ? [provider] : Object.keys(dataStorage);
  250. providers.forEach(function (provider2) {
  251. var prefixes = typeof provider2 === "string" && typeof prefix === "string" ? [prefix] : Object.keys(dataStorage[provider2] || {});
  252. prefixes.forEach(function (prefix2) {
  253. var storage = getStorage(provider2, prefix2);
  254. allIcons = allIcons.concat(
  255. Object.keys(storage.icons).map(
  256. function (name) { return (provider2 !== "" ? "@" + provider2 + ":" : "") + prefix2 + ":" + name; }
  257. )
  258. );
  259. });
  260. });
  261. return allIcons;
  262. }
  263. var simpleNames = false;
  264. function allowSimpleNames(allow) {
  265. if (typeof allow === "boolean") {
  266. simpleNames = allow;
  267. }
  268. return simpleNames;
  269. }
  270. function getIconData(name) {
  271. var icon = typeof name === "string" ? stringToIcon(name, true, simpleNames) : name;
  272. if (icon) {
  273. var storage = getStorage(icon.provider, icon.prefix);
  274. var iconName = icon.name;
  275. return storage.icons[iconName] || (storage.missing.has(iconName) ? null : void 0);
  276. }
  277. }
  278. function addIcon(name, data) {
  279. var icon = stringToIcon(name, true, simpleNames);
  280. if (!icon) {
  281. return false;
  282. }
  283. var storage = getStorage(icon.provider, icon.prefix);
  284. return addIconToStorage(storage, icon.name, data);
  285. }
  286. function addCollection(data, provider) {
  287. if (typeof data !== "object") {
  288. return false;
  289. }
  290. if (typeof provider !== "string") {
  291. provider = data.provider || "";
  292. }
  293. if (simpleNames && !provider && !data.prefix) {
  294. var added = false;
  295. if (quicklyValidateIconSet(data)) {
  296. data.prefix = "";
  297. parseIconSet(data, function (name, icon) {
  298. if (icon && addIcon(name, icon)) {
  299. added = true;
  300. }
  301. });
  302. }
  303. return added;
  304. }
  305. var prefix = data.prefix;
  306. if (!validateIconName({
  307. provider: provider,
  308. prefix: prefix,
  309. name: "a"
  310. })) {
  311. return false;
  312. }
  313. var storage = getStorage(provider, prefix);
  314. return !!addIconSet(storage, data);
  315. }
  316. function iconExists(name) {
  317. return !!getIconData(name);
  318. }
  319. function getIcon(name) {
  320. var result = getIconData(name);
  321. return result ? Object.assign({}, defaultIconProps,
  322. result) : null;
  323. }
  324. var defaultIconSizeCustomisations = Object.freeze({
  325. width: null,
  326. height: null
  327. });
  328. var defaultIconCustomisations = Object.freeze(Object.assign({}, defaultIconSizeCustomisations,
  329. defaultIconTransformations));
  330. var unitsSplit = /(-?[0-9.]*[0-9]+[0-9.]*)/g;
  331. var unitsTest = /^-?[0-9.]*[0-9]+[0-9.]*$/g;
  332. function calculateSize(size, ratio, precision) {
  333. if (ratio === 1) {
  334. return size;
  335. }
  336. precision = precision || 100;
  337. if (typeof size === "number") {
  338. return Math.ceil(size * ratio * precision) / precision;
  339. }
  340. if (typeof size !== "string") {
  341. return size;
  342. }
  343. var oldParts = size.split(unitsSplit);
  344. if (oldParts === null || !oldParts.length) {
  345. return size;
  346. }
  347. var newParts = [];
  348. var code = oldParts.shift();
  349. var isNumber = unitsTest.test(code);
  350. while (true) {
  351. if (isNumber) {
  352. var num = parseFloat(code);
  353. if (isNaN(num)) {
  354. newParts.push(code);
  355. } else {
  356. newParts.push(Math.ceil(num * ratio * precision) / precision);
  357. }
  358. } else {
  359. newParts.push(code);
  360. }
  361. code = oldParts.shift();
  362. if (code === void 0) {
  363. return newParts.join("");
  364. }
  365. isNumber = !isNumber;
  366. }
  367. }
  368. var isUnsetKeyword = function (value) { return value === "unset" || value === "undefined" || value === "none"; };
  369. function iconToSVG(icon, customisations) {
  370. var fullIcon = Object.assign({}, defaultIconProps,
  371. icon);
  372. var fullCustomisations = Object.assign({}, defaultIconCustomisations,
  373. customisations);
  374. var box = {
  375. left: fullIcon.left,
  376. top: fullIcon.top,
  377. width: fullIcon.width,
  378. height: fullIcon.height
  379. };
  380. var body = fullIcon.body;
  381. [fullIcon, fullCustomisations].forEach(function (props) {
  382. var transformations = [];
  383. var hFlip = props.hFlip;
  384. var vFlip = props.vFlip;
  385. var rotation = props.rotate;
  386. if (hFlip) {
  387. if (vFlip) {
  388. rotation += 2;
  389. } else {
  390. transformations.push(
  391. "translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")"
  392. );
  393. transformations.push("scale(-1 1)");
  394. box.top = box.left = 0;
  395. }
  396. } else if (vFlip) {
  397. transformations.push(
  398. "translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")"
  399. );
  400. transformations.push("scale(1 -1)");
  401. box.top = box.left = 0;
  402. }
  403. var tempValue;
  404. if (rotation < 0) {
  405. rotation -= Math.floor(rotation / 4) * 4;
  406. }
  407. rotation = rotation % 4;
  408. switch (rotation) {
  409. case 1:
  410. tempValue = box.height / 2 + box.top;
  411. transformations.unshift(
  412. "rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")"
  413. );
  414. break;
  415. case 2:
  416. transformations.unshift(
  417. "rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")"
  418. );
  419. break;
  420. case 3:
  421. tempValue = box.width / 2 + box.left;
  422. transformations.unshift(
  423. "rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")"
  424. );
  425. break;
  426. }
  427. if (rotation % 2 === 1) {
  428. if (box.left !== box.top) {
  429. tempValue = box.left;
  430. box.left = box.top;
  431. box.top = tempValue;
  432. }
  433. if (box.width !== box.height) {
  434. tempValue = box.width;
  435. box.width = box.height;
  436. box.height = tempValue;
  437. }
  438. }
  439. if (transformations.length) {
  440. body = '<g transform="' + transformations.join(" ") + '">' + body + "</g>";
  441. }
  442. });
  443. var customisationsWidth = fullCustomisations.width;
  444. var customisationsHeight = fullCustomisations.height;
  445. var boxWidth = box.width;
  446. var boxHeight = box.height;
  447. var width;
  448. var height;
  449. if (customisationsWidth === null) {
  450. height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
  451. width = calculateSize(height, boxWidth / boxHeight);
  452. } else {
  453. width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
  454. height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
  455. }
  456. var attributes = {};
  457. var setAttr = function (prop, value) {
  458. if (!isUnsetKeyword(value)) {
  459. attributes[prop] = value.toString();
  460. }
  461. };
  462. setAttr("width", width);
  463. setAttr("height", height);
  464. attributes.viewBox = box.left.toString() + " " + box.top.toString() + " " + boxWidth.toString() + " " + boxHeight.toString();
  465. return {
  466. attributes: attributes,
  467. body: body
  468. };
  469. }
  470. var regex = /\sid="(\S+)"/g;
  471. var randomPrefix = "IconifyId" + Date.now().toString(16) + (Math.random() * 16777216 | 0).toString(16);
  472. var counter = 0;
  473. function replaceIDs(body, prefix) {
  474. if ( prefix === void 0 ) prefix = randomPrefix;
  475. var ids = [];
  476. var match;
  477. while (match = regex.exec(body)) {
  478. ids.push(match[1]);
  479. }
  480. if (!ids.length) {
  481. return body;
  482. }
  483. var suffix = "suffix" + (Math.random() * 16777216 | Date.now()).toString(16);
  484. ids.forEach(function (id) {
  485. var newID = typeof prefix === "function" ? prefix(id) : prefix + (counter++).toString();
  486. var escapedID = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  487. body = body.replace(
  488. new RegExp('([#;"])(' + escapedID + ')([")]|\\.[a-z])', "g"),
  489. "$1" + newID + suffix + "$3"
  490. );
  491. });
  492. body = body.replace(new RegExp(suffix, "g"), "");
  493. return body;
  494. }
  495. var browserStorageConfig = {
  496. local: true,
  497. session: true
  498. };
  499. var browserStorageEmptyItems = {
  500. local: /* @__PURE__ */ new Set(),
  501. session: /* @__PURE__ */ new Set()
  502. };
  503. var browserStorageStatus = false;
  504. function setBrowserStorageStatus(status) {
  505. browserStorageStatus = status;
  506. }
  507. var browserCacheVersion = "iconify2";
  508. var browserCachePrefix = "iconify";
  509. var browserCacheCountKey = browserCachePrefix + "-count";
  510. var browserCacheVersionKey = browserCachePrefix + "-version";
  511. var browserStorageHour = 36e5;
  512. var browserStorageCacheExpiration = 168;
  513. function getStoredItem(func, key) {
  514. try {
  515. return func.getItem(key);
  516. } catch (err) {
  517. }
  518. }
  519. function setStoredItem(func, key, value) {
  520. try {
  521. func.setItem(key, value);
  522. return true;
  523. } catch (err) {
  524. }
  525. }
  526. function removeStoredItem(func, key) {
  527. try {
  528. func.removeItem(key);
  529. } catch (err) {
  530. }
  531. }
  532. function setBrowserStorageItemsCount(storage, value) {
  533. return setStoredItem(storage, browserCacheCountKey, value.toString());
  534. }
  535. function getBrowserStorageItemsCount(storage) {
  536. return parseInt(getStoredItem(storage, browserCacheCountKey)) || 0;
  537. }
  538. var _window$2 = typeof window === "undefined" ? {} : window;
  539. function getBrowserStorage(key) {
  540. var attr = key + "Storage";
  541. try {
  542. if (_window$2 && _window$2[attr] && typeof _window$2[attr].length === "number") {
  543. return _window$2[attr];
  544. }
  545. } catch (err) {
  546. }
  547. browserStorageConfig[key] = false;
  548. }
  549. function iterateBrowserStorage(key, callback) {
  550. var func = getBrowserStorage(key);
  551. if (!func) {
  552. return;
  553. }
  554. var version = getStoredItem(func, browserCacheVersionKey);
  555. if (version !== browserCacheVersion) {
  556. if (version) {
  557. var total2 = getBrowserStorageItemsCount(func);
  558. for (var i = 0; i < total2; i++) {
  559. removeStoredItem(func, browserCachePrefix + i.toString());
  560. }
  561. }
  562. setStoredItem(func, browserCacheVersionKey, browserCacheVersion);
  563. setBrowserStorageItemsCount(func, 0);
  564. return;
  565. }
  566. var minTime = Math.floor(Date.now() / browserStorageHour) - browserStorageCacheExpiration;
  567. var parseItem = function (index) {
  568. var name = browserCachePrefix + index.toString();
  569. var item = getStoredItem(func, name);
  570. if (typeof item !== "string") {
  571. return;
  572. }
  573. try {
  574. var data = JSON.parse(item);
  575. if (typeof data === "object" && typeof data.cached === "number" && data.cached > minTime && typeof data.provider === "string" && typeof data.data === "object" && typeof data.data.prefix === "string" && callback(data, index)) {
  576. return true;
  577. }
  578. } catch (err) {
  579. }
  580. removeStoredItem(func, name);
  581. };
  582. var total = getBrowserStorageItemsCount(func);
  583. for (var i$1 = total - 1; i$1 >= 0; i$1--) {
  584. if (!parseItem(i$1)) {
  585. if (i$1 === total - 1) {
  586. total--;
  587. setBrowserStorageItemsCount(func, total);
  588. } else {
  589. browserStorageEmptyItems[key].add(i$1);
  590. }
  591. }
  592. }
  593. }
  594. function initBrowserStorage() {
  595. if (browserStorageStatus) {
  596. return;
  597. }
  598. setBrowserStorageStatus(true);
  599. for (var key in browserStorageConfig) {
  600. iterateBrowserStorage(key, function (item) {
  601. var iconSet = item.data;
  602. var provider = item.provider;
  603. var prefix = iconSet.prefix;
  604. var storage = getStorage(
  605. provider,
  606. prefix
  607. );
  608. if (!addIconSet(storage, iconSet).length) {
  609. return false;
  610. }
  611. var lastModified = iconSet.lastModified || -1;
  612. storage.lastModifiedCached = storage.lastModifiedCached ? Math.min(storage.lastModifiedCached, lastModified) : lastModified;
  613. return true;
  614. });
  615. }
  616. }
  617. function toggleBrowserCache(storage, value) {
  618. switch (storage) {
  619. case "local":
  620. case "session":
  621. browserStorageConfig[storage] = value;
  622. break;
  623. case "all":
  624. for (var key in browserStorageConfig) {
  625. browserStorageConfig[key] = value;
  626. }
  627. break;
  628. }
  629. }
  630. var storage = /* @__PURE__ */ Object.create(null);
  631. function setAPIModule(provider, item) {
  632. storage[provider] = item;
  633. }
  634. function getAPIModule(provider) {
  635. return storage[provider] || storage[""];
  636. }
  637. function createAPIConfig(source) {
  638. var resources;
  639. if (typeof source.resources === "string") {
  640. resources = [source.resources];
  641. } else {
  642. resources = source.resources;
  643. if (!(resources instanceof Array) || !resources.length) {
  644. return null;
  645. }
  646. }
  647. var result = {
  648. resources: resources,
  649. path: source.path || "/",
  650. maxURL: source.maxURL || 500,
  651. rotate: source.rotate || 750,
  652. timeout: source.timeout || 5e3,
  653. random: source.random === true,
  654. index: source.index || 0,
  655. dataAfterTimeout: source.dataAfterTimeout !== false
  656. };
  657. return result;
  658. }
  659. var configStorage = /* @__PURE__ */ Object.create(null);
  660. var fallBackAPISources = [
  661. "https://api.simplesvg.com",
  662. "https://api.unisvg.com"
  663. ];
  664. var fallBackAPI = [];
  665. while (fallBackAPISources.length > 0) {
  666. if (fallBackAPISources.length === 1) {
  667. fallBackAPI.push(fallBackAPISources.shift());
  668. } else {
  669. if (Math.random() > 0.5) {
  670. fallBackAPI.push(fallBackAPISources.shift());
  671. } else {
  672. fallBackAPI.push(fallBackAPISources.pop());
  673. }
  674. }
  675. }
  676. configStorage[""] = createAPIConfig({
  677. resources: ["https://api.iconify.design"].concat(fallBackAPI)
  678. });
  679. function addAPIProvider(provider, customConfig) {
  680. var config = createAPIConfig(customConfig);
  681. if (config === null) {
  682. return false;
  683. }
  684. configStorage[provider] = config;
  685. return true;
  686. }
  687. function getAPIConfig(provider) {
  688. return configStorage[provider];
  689. }
  690. function listAPIProviders() {
  691. return Object.keys(configStorage);
  692. }
  693. var detectFetch = function () {
  694. var callback;
  695. try {
  696. callback = fetch;
  697. if (typeof callback === "function") {
  698. return callback;
  699. }
  700. } catch (err) {
  701. }
  702. };
  703. var fetchModule = detectFetch();
  704. function setFetch(fetch2) {
  705. fetchModule = fetch2;
  706. }
  707. function getFetch() {
  708. return fetchModule;
  709. }
  710. function calculateMaxLength(provider, prefix) {
  711. var config = getAPIConfig(provider);
  712. if (!config) {
  713. return 0;
  714. }
  715. var result;
  716. if (!config.maxURL) {
  717. result = 0;
  718. } else {
  719. var maxHostLength = 0;
  720. config.resources.forEach(function (item) {
  721. var host = item;
  722. maxHostLength = Math.max(maxHostLength, host.length);
  723. });
  724. var url = prefix + ".json?icons=";
  725. result = config.maxURL - maxHostLength - config.path.length - url.length;
  726. }
  727. return result;
  728. }
  729. function shouldAbort(status) {
  730. return status === 404;
  731. }
  732. var prepare = function (provider, prefix, icons) {
  733. var results = [];
  734. var maxLength = calculateMaxLength(provider, prefix);
  735. var type = "icons";
  736. var item = {
  737. type: type,
  738. provider: provider,
  739. prefix: prefix,
  740. icons: []
  741. };
  742. var length = 0;
  743. icons.forEach(function (name, index) {
  744. length += name.length + 1;
  745. if (length >= maxLength && index > 0) {
  746. results.push(item);
  747. item = {
  748. type: type,
  749. provider: provider,
  750. prefix: prefix,
  751. icons: []
  752. };
  753. length = name.length;
  754. }
  755. item.icons.push(name);
  756. });
  757. results.push(item);
  758. return results;
  759. };
  760. function getPath(provider) {
  761. if (typeof provider === "string") {
  762. var config = getAPIConfig(provider);
  763. if (config) {
  764. return config.path;
  765. }
  766. }
  767. return "/";
  768. }
  769. var send = function (host, params, callback) {
  770. if (!fetchModule) {
  771. callback("abort", 424);
  772. return;
  773. }
  774. var path = getPath(params.provider);
  775. switch (params.type) {
  776. case "icons": {
  777. var prefix = params.prefix;
  778. var icons = params.icons;
  779. var iconsList = icons.join(",");
  780. var urlParams = new URLSearchParams({
  781. icons: iconsList
  782. });
  783. path += prefix + ".json?" + urlParams.toString();
  784. break;
  785. }
  786. case "custom": {
  787. var uri = params.uri;
  788. path += uri.slice(0, 1) === "/" ? uri.slice(1) : uri;
  789. break;
  790. }
  791. default:
  792. callback("abort", 400);
  793. return;
  794. }
  795. var defaultError = 503;
  796. fetchModule(host + path).then(function (response) {
  797. var status = response.status;
  798. if (status !== 200) {
  799. setTimeout(function () {
  800. callback(shouldAbort(status) ? "abort" : "next", status);
  801. });
  802. return;
  803. }
  804. defaultError = 501;
  805. return response.json();
  806. }).then(function (data) {
  807. if (typeof data !== "object" || data === null) {
  808. setTimeout(function () {
  809. if (data === 404) {
  810. callback("abort", data);
  811. } else {
  812. callback("next", defaultError);
  813. }
  814. });
  815. return;
  816. }
  817. setTimeout(function () {
  818. callback("success", data);
  819. });
  820. }).catch(function () {
  821. callback("next", defaultError);
  822. });
  823. };
  824. var fetchAPIModule = {
  825. prepare: prepare,
  826. send: send
  827. };
  828. function sortIcons(icons) {
  829. var result = {
  830. loaded: [],
  831. missing: [],
  832. pending: []
  833. };
  834. var storage = /* @__PURE__ */ Object.create(null);
  835. icons.sort(function (a, b) {
  836. if (a.provider !== b.provider) {
  837. return a.provider.localeCompare(b.provider);
  838. }
  839. if (a.prefix !== b.prefix) {
  840. return a.prefix.localeCompare(b.prefix);
  841. }
  842. return a.name.localeCompare(b.name);
  843. });
  844. var lastIcon = {
  845. provider: "",
  846. prefix: "",
  847. name: ""
  848. };
  849. icons.forEach(function (icon) {
  850. if (lastIcon.name === icon.name && lastIcon.prefix === icon.prefix && lastIcon.provider === icon.provider) {
  851. return;
  852. }
  853. lastIcon = icon;
  854. var provider = icon.provider;
  855. var prefix = icon.prefix;
  856. var name = icon.name;
  857. var providerStorage = storage[provider] || (storage[provider] = /* @__PURE__ */ Object.create(null));
  858. var localStorage = providerStorage[prefix] || (providerStorage[prefix] = getStorage(provider, prefix));
  859. var list;
  860. if (name in localStorage.icons) {
  861. list = result.loaded;
  862. } else if (prefix === "" || localStorage.missing.has(name)) {
  863. list = result.missing;
  864. } else {
  865. list = result.pending;
  866. }
  867. var item = {
  868. provider: provider,
  869. prefix: prefix,
  870. name: name
  871. };
  872. list.push(item);
  873. });
  874. return result;
  875. }
  876. function removeCallback(storages, id) {
  877. storages.forEach(function (storage) {
  878. var items = storage.loaderCallbacks;
  879. if (items) {
  880. storage.loaderCallbacks = items.filter(function (row) { return row.id !== id; });
  881. }
  882. });
  883. }
  884. function updateCallbacks(storage) {
  885. if (!storage.pendingCallbacksFlag) {
  886. storage.pendingCallbacksFlag = true;
  887. setTimeout(function () {
  888. storage.pendingCallbacksFlag = false;
  889. var items = storage.loaderCallbacks ? storage.loaderCallbacks.slice(0) : [];
  890. if (!items.length) {
  891. return;
  892. }
  893. var hasPending = false;
  894. var provider = storage.provider;
  895. var prefix = storage.prefix;
  896. items.forEach(function (item) {
  897. var icons = item.icons;
  898. var oldLength = icons.pending.length;
  899. icons.pending = icons.pending.filter(function (icon) {
  900. if (icon.prefix !== prefix) {
  901. return true;
  902. }
  903. var name = icon.name;
  904. if (storage.icons[name]) {
  905. icons.loaded.push({
  906. provider: provider,
  907. prefix: prefix,
  908. name: name
  909. });
  910. } else if (storage.missing.has(name)) {
  911. icons.missing.push({
  912. provider: provider,
  913. prefix: prefix,
  914. name: name
  915. });
  916. } else {
  917. hasPending = true;
  918. return true;
  919. }
  920. return false;
  921. });
  922. if (icons.pending.length !== oldLength) {
  923. if (!hasPending) {
  924. removeCallback([storage], item.id);
  925. }
  926. item.callback(
  927. icons.loaded.slice(0),
  928. icons.missing.slice(0),
  929. icons.pending.slice(0),
  930. item.abort
  931. );
  932. }
  933. });
  934. });
  935. }
  936. }
  937. var idCounter = 0;
  938. function storeCallback(callback, icons, pendingSources) {
  939. var id = idCounter++;
  940. var abort = removeCallback.bind(null, pendingSources, id);
  941. if (!icons.pending.length) {
  942. return abort;
  943. }
  944. var item = {
  945. id: id,
  946. icons: icons,
  947. callback: callback,
  948. abort: abort
  949. };
  950. pendingSources.forEach(function (storage) {
  951. (storage.loaderCallbacks || (storage.loaderCallbacks = [])).push(item);
  952. });
  953. return abort;
  954. }
  955. function listToIcons(list, validate, simpleNames) {
  956. if ( validate === void 0 ) validate = true;
  957. if ( simpleNames === void 0 ) simpleNames = false;
  958. var result = [];
  959. list.forEach(function (item) {
  960. var icon = typeof item === "string" ? stringToIcon(item, validate, simpleNames) : item;
  961. if (icon) {
  962. result.push(icon);
  963. }
  964. });
  965. return result;
  966. }
  967. // src/config.ts
  968. var defaultConfig = {
  969. resources: [],
  970. index: 0,
  971. timeout: 2e3,
  972. rotate: 750,
  973. random: false,
  974. dataAfterTimeout: false
  975. };
  976. // src/query.ts
  977. function sendQuery(config, payload, query, done) {
  978. var resourcesCount = config.resources.length;
  979. var startIndex = config.random ? Math.floor(Math.random() * resourcesCount) : config.index;
  980. var resources;
  981. if (config.random) {
  982. var list = config.resources.slice(0);
  983. resources = [];
  984. while (list.length > 1) {
  985. var nextIndex = Math.floor(Math.random() * list.length);
  986. resources.push(list[nextIndex]);
  987. list = list.slice(0, nextIndex).concat(list.slice(nextIndex + 1));
  988. }
  989. resources = resources.concat(list);
  990. } else {
  991. resources = config.resources.slice(startIndex).concat(config.resources.slice(0, startIndex));
  992. }
  993. var startTime = Date.now();
  994. var status = "pending";
  995. var queriesSent = 0;
  996. var lastError;
  997. var timer = null;
  998. var queue = [];
  999. var doneCallbacks = [];
  1000. if (typeof done === "function") {
  1001. doneCallbacks.push(done);
  1002. }
  1003. function resetTimer() {
  1004. if (timer) {
  1005. clearTimeout(timer);
  1006. timer = null;
  1007. }
  1008. }
  1009. function abort() {
  1010. if (status === "pending") {
  1011. status = "aborted";
  1012. }
  1013. resetTimer();
  1014. queue.forEach(function (item) {
  1015. if (item.status === "pending") {
  1016. item.status = "aborted";
  1017. }
  1018. });
  1019. queue = [];
  1020. }
  1021. function subscribe(callback, overwrite) {
  1022. if (overwrite) {
  1023. doneCallbacks = [];
  1024. }
  1025. if (typeof callback === "function") {
  1026. doneCallbacks.push(callback);
  1027. }
  1028. }
  1029. function getQueryStatus() {
  1030. return {
  1031. startTime: startTime,
  1032. payload: payload,
  1033. status: status,
  1034. queriesSent: queriesSent,
  1035. queriesPending: queue.length,
  1036. subscribe: subscribe,
  1037. abort: abort
  1038. };
  1039. }
  1040. function failQuery() {
  1041. status = "failed";
  1042. doneCallbacks.forEach(function (callback) {
  1043. callback(void 0, lastError);
  1044. });
  1045. }
  1046. function clearQueue() {
  1047. queue.forEach(function (item) {
  1048. if (item.status === "pending") {
  1049. item.status = "aborted";
  1050. }
  1051. });
  1052. queue = [];
  1053. }
  1054. function moduleResponse(item, response, data) {
  1055. var isError = response !== "success";
  1056. queue = queue.filter(function (queued) { return queued !== item; });
  1057. switch (status) {
  1058. case "pending":
  1059. break;
  1060. case "failed":
  1061. if (isError || !config.dataAfterTimeout) {
  1062. return;
  1063. }
  1064. break;
  1065. default:
  1066. return;
  1067. }
  1068. if (response === "abort") {
  1069. lastError = data;
  1070. failQuery();
  1071. return;
  1072. }
  1073. if (isError) {
  1074. lastError = data;
  1075. if (!queue.length) {
  1076. if (!resources.length) {
  1077. failQuery();
  1078. } else {
  1079. execNext();
  1080. }
  1081. }
  1082. return;
  1083. }
  1084. resetTimer();
  1085. clearQueue();
  1086. if (!config.random) {
  1087. var index = config.resources.indexOf(item.resource);
  1088. if (index !== -1 && index !== config.index) {
  1089. config.index = index;
  1090. }
  1091. }
  1092. status = "completed";
  1093. doneCallbacks.forEach(function (callback) {
  1094. callback(data);
  1095. });
  1096. }
  1097. function execNext() {
  1098. if (status !== "pending") {
  1099. return;
  1100. }
  1101. resetTimer();
  1102. var resource = resources.shift();
  1103. if (resource === void 0) {
  1104. if (queue.length) {
  1105. timer = setTimeout(function () {
  1106. resetTimer();
  1107. if (status === "pending") {
  1108. clearQueue();
  1109. failQuery();
  1110. }
  1111. }, config.timeout);
  1112. return;
  1113. }
  1114. failQuery();
  1115. return;
  1116. }
  1117. var item = {
  1118. status: "pending",
  1119. resource: resource,
  1120. callback: function (status2, data) {
  1121. moduleResponse(item, status2, data);
  1122. }
  1123. };
  1124. queue.push(item);
  1125. queriesSent++;
  1126. timer = setTimeout(execNext, config.rotate);
  1127. query(resource, payload, item.callback);
  1128. }
  1129. setTimeout(execNext);
  1130. return getQueryStatus;
  1131. }
  1132. // src/index.ts
  1133. function initRedundancy(cfg) {
  1134. var config = Object.assign({}, defaultConfig,
  1135. cfg);
  1136. var queries = [];
  1137. function cleanup() {
  1138. queries = queries.filter(function (item) { return item().status === "pending"; });
  1139. }
  1140. function query(payload, queryCallback, doneCallback) {
  1141. var query2 = sendQuery(
  1142. config,
  1143. payload,
  1144. queryCallback,
  1145. function (data, error) {
  1146. cleanup();
  1147. if (doneCallback) {
  1148. doneCallback(data, error);
  1149. }
  1150. }
  1151. );
  1152. queries.push(query2);
  1153. return query2;
  1154. }
  1155. function find(callback) {
  1156. return queries.find(function (value) {
  1157. return callback(value);
  1158. }) || null;
  1159. }
  1160. var instance = {
  1161. query: query,
  1162. find: find,
  1163. setIndex: function (index) {
  1164. config.index = index;
  1165. },
  1166. getIndex: function () { return config.index; },
  1167. cleanup: cleanup
  1168. };
  1169. return instance;
  1170. }
  1171. function emptyCallback$1() {
  1172. }
  1173. var redundancyCache = /* @__PURE__ */ Object.create(null);
  1174. function getRedundancyCache(provider) {
  1175. if (!redundancyCache[provider]) {
  1176. var config = getAPIConfig(provider);
  1177. if (!config) {
  1178. return;
  1179. }
  1180. var redundancy = initRedundancy(config);
  1181. var cachedReundancy = {
  1182. config: config,
  1183. redundancy: redundancy
  1184. };
  1185. redundancyCache[provider] = cachedReundancy;
  1186. }
  1187. return redundancyCache[provider];
  1188. }
  1189. function sendAPIQuery(target, query, callback) {
  1190. var redundancy;
  1191. var send;
  1192. if (typeof target === "string") {
  1193. var api = getAPIModule(target);
  1194. if (!api) {
  1195. callback(void 0, 424);
  1196. return emptyCallback$1;
  1197. }
  1198. send = api.send;
  1199. var cached = getRedundancyCache(target);
  1200. if (cached) {
  1201. redundancy = cached.redundancy;
  1202. }
  1203. } else {
  1204. var config = createAPIConfig(target);
  1205. if (config) {
  1206. redundancy = initRedundancy(config);
  1207. var moduleKey = target.resources ? target.resources[0] : "";
  1208. var api$1 = getAPIModule(moduleKey);
  1209. if (api$1) {
  1210. send = api$1.send;
  1211. }
  1212. }
  1213. }
  1214. if (!redundancy || !send) {
  1215. callback(void 0, 424);
  1216. return emptyCallback$1;
  1217. }
  1218. return redundancy.query(query, send, callback)().abort;
  1219. }
  1220. function updateLastModified(storage, lastModified) {
  1221. var lastValue = storage.lastModifiedCached;
  1222. if (lastValue && lastValue >= lastModified) {
  1223. return lastValue === lastModified;
  1224. }
  1225. storage.lastModifiedCached = lastModified;
  1226. if (lastValue) {
  1227. for (var key in browserStorageConfig) {
  1228. iterateBrowserStorage(key, function (item) {
  1229. var iconSet = item.data;
  1230. return item.provider !== storage.provider || iconSet.prefix !== storage.prefix || iconSet.lastModified === lastModified;
  1231. });
  1232. }
  1233. }
  1234. return true;
  1235. }
  1236. function storeInBrowserStorage(storage, data) {
  1237. if (!browserStorageStatus) {
  1238. initBrowserStorage();
  1239. }
  1240. function store(key) {
  1241. var func;
  1242. if (!browserStorageConfig[key] || !(func = getBrowserStorage(key))) {
  1243. return;
  1244. }
  1245. var set = browserStorageEmptyItems[key];
  1246. var index;
  1247. if (set.size) {
  1248. set.delete(index = Array.from(set).shift());
  1249. } else {
  1250. index = getBrowserStorageItemsCount(func);
  1251. if (!setBrowserStorageItemsCount(func, index + 1)) {
  1252. return;
  1253. }
  1254. }
  1255. var item = {
  1256. cached: Math.floor(Date.now() / browserStorageHour),
  1257. provider: storage.provider,
  1258. data: data
  1259. };
  1260. return setStoredItem(
  1261. func,
  1262. browserCachePrefix + index.toString(),
  1263. JSON.stringify(item)
  1264. );
  1265. }
  1266. if (data.lastModified && !updateLastModified(storage, data.lastModified)) {
  1267. return;
  1268. }
  1269. if (!Object.keys(data.icons).length) {
  1270. return;
  1271. }
  1272. if (data.not_found) {
  1273. data = Object.assign({}, data);
  1274. delete data.not_found;
  1275. }
  1276. if (!store("local")) {
  1277. store("session");
  1278. }
  1279. }
  1280. function emptyCallback() {
  1281. }
  1282. function loadedNewIcons(storage) {
  1283. if (!storage.iconsLoaderFlag) {
  1284. storage.iconsLoaderFlag = true;
  1285. setTimeout(function () {
  1286. storage.iconsLoaderFlag = false;
  1287. updateCallbacks(storage);
  1288. });
  1289. }
  1290. }
  1291. function loadNewIcons(storage, icons) {
  1292. if (!storage.iconsToLoad) {
  1293. storage.iconsToLoad = icons;
  1294. } else {
  1295. storage.iconsToLoad = storage.iconsToLoad.concat(icons).sort();
  1296. }
  1297. if (!storage.iconsQueueFlag) {
  1298. storage.iconsQueueFlag = true;
  1299. setTimeout(function () {
  1300. storage.iconsQueueFlag = false;
  1301. var provider = storage.provider;
  1302. var prefix = storage.prefix;
  1303. var icons2 = storage.iconsToLoad;
  1304. delete storage.iconsToLoad;
  1305. var api;
  1306. if (!icons2 || !(api = getAPIModule(provider))) {
  1307. return;
  1308. }
  1309. var params = api.prepare(provider, prefix, icons2);
  1310. params.forEach(function (item) {
  1311. sendAPIQuery(provider, item, function (data) {
  1312. if (typeof data !== "object") {
  1313. item.icons.forEach(function (name) {
  1314. storage.missing.add(name);
  1315. });
  1316. } else {
  1317. try {
  1318. var parsed = addIconSet(
  1319. storage,
  1320. data
  1321. );
  1322. if (!parsed.length) {
  1323. return;
  1324. }
  1325. var pending = storage.pendingIcons;
  1326. if (pending) {
  1327. parsed.forEach(function (name) {
  1328. pending.delete(name);
  1329. });
  1330. }
  1331. storeInBrowserStorage(storage, data);
  1332. } catch (err) {
  1333. console.error(err);
  1334. }
  1335. }
  1336. loadedNewIcons(storage);
  1337. });
  1338. });
  1339. });
  1340. }
  1341. }
  1342. var isPending = function (icon) {
  1343. var storage = getStorage(
  1344. icon.provider,
  1345. icon.prefix
  1346. );
  1347. var pending = storage.pendingIcons;
  1348. return !!(pending && pending.has(icon.name));
  1349. };
  1350. var loadIcons = function (icons, callback) {
  1351. var cleanedIcons = listToIcons(icons, true, allowSimpleNames());
  1352. var sortedIcons = sortIcons(cleanedIcons);
  1353. if (!sortedIcons.pending.length) {
  1354. var callCallback = true;
  1355. if (callback) {
  1356. setTimeout(function () {
  1357. if (callCallback) {
  1358. callback(
  1359. sortedIcons.loaded,
  1360. sortedIcons.missing,
  1361. sortedIcons.pending,
  1362. emptyCallback
  1363. );
  1364. }
  1365. });
  1366. }
  1367. return function () {
  1368. callCallback = false;
  1369. };
  1370. }
  1371. var newIcons = /* @__PURE__ */ Object.create(null);
  1372. var sources = [];
  1373. var lastProvider, lastPrefix;
  1374. sortedIcons.pending.forEach(function (icon) {
  1375. var provider = icon.provider;
  1376. var prefix = icon.prefix;
  1377. if (prefix === lastPrefix && provider === lastProvider) {
  1378. return;
  1379. }
  1380. lastProvider = provider;
  1381. lastPrefix = prefix;
  1382. sources.push(getStorage(provider, prefix));
  1383. var providerNewIcons = newIcons[provider] || (newIcons[provider] = /* @__PURE__ */ Object.create(null));
  1384. if (!providerNewIcons[prefix]) {
  1385. providerNewIcons[prefix] = [];
  1386. }
  1387. });
  1388. sortedIcons.pending.forEach(function (icon) {
  1389. var provider = icon.provider;
  1390. var prefix = icon.prefix;
  1391. var name = icon.name;
  1392. var storage = getStorage(provider, prefix);
  1393. var pendingQueue = storage.pendingIcons || (storage.pendingIcons = /* @__PURE__ */ new Set());
  1394. if (!pendingQueue.has(name)) {
  1395. pendingQueue.add(name);
  1396. newIcons[provider][prefix].push(name);
  1397. }
  1398. });
  1399. sources.forEach(function (storage) {
  1400. var provider = storage.provider;
  1401. var prefix = storage.prefix;
  1402. if (newIcons[provider][prefix].length) {
  1403. loadNewIcons(storage, newIcons[provider][prefix]);
  1404. }
  1405. });
  1406. return callback ? storeCallback(callback, sortedIcons, sources) : emptyCallback;
  1407. };
  1408. var loadIcon = function (icon) {
  1409. return new Promise(function (fulfill, reject) {
  1410. var iconObj = typeof icon === "string" ? stringToIcon(icon, true) : icon;
  1411. if (!iconObj) {
  1412. reject(icon);
  1413. return;
  1414. }
  1415. loadIcons([iconObj || icon], function (loaded) {
  1416. if (loaded.length && iconObj) {
  1417. var data = getIconData(iconObj);
  1418. if (data) {
  1419. fulfill(Object.assign({}, defaultIconProps,
  1420. data));
  1421. return;
  1422. }
  1423. }
  1424. reject(icon);
  1425. });
  1426. });
  1427. };
  1428. function mergeCustomisations(defaults, item) {
  1429. var result = Object.assign({}, defaults);
  1430. for (var key in item) {
  1431. var value = item[key];
  1432. var valueType = typeof value;
  1433. if (key in defaultIconSizeCustomisations) {
  1434. if (value === null || value && (valueType === "string" || valueType === "number")) {
  1435. result[key] = value;
  1436. }
  1437. } else if (valueType === typeof result[key]) {
  1438. result[key] = key === "rotate" ? value % 4 : value;
  1439. }
  1440. }
  1441. return result;
  1442. }
  1443. var defaultExtendedIconCustomisations = Object.assign({}, defaultIconCustomisations,
  1444. {inline: false});
  1445. /**
  1446. * Class names
  1447. */
  1448. var blockClass = 'iconify';
  1449. var inlineClass = 'iconify-inline';
  1450. /**
  1451. * Names of properties to add to nodes
  1452. */
  1453. var elementDataProperty = ('iconifyData' + Date.now());
  1454. /**
  1455. * List of root nodes
  1456. */
  1457. var nodes = [];
  1458. /**
  1459. * Find node
  1460. */
  1461. function findRootNode(node) {
  1462. for (var i = 0; i < nodes.length; i++) {
  1463. var item = nodes[i];
  1464. var root = typeof item.node === 'function' ? item.node() : item.node;
  1465. if (root === node) {
  1466. return item;
  1467. }
  1468. }
  1469. }
  1470. /**
  1471. * Add extra root node
  1472. */
  1473. function addRootNode(root, autoRemove) {
  1474. if ( autoRemove === void 0 ) autoRemove = false;
  1475. var node = findRootNode(root);
  1476. if (node) {
  1477. // Node already exist: switch type if needed
  1478. if (node.temporary) {
  1479. node.temporary = autoRemove;
  1480. }
  1481. return node;
  1482. }
  1483. // Create item, add it to list
  1484. node = {
  1485. node: root,
  1486. temporary: autoRemove,
  1487. };
  1488. nodes.push(node);
  1489. return node;
  1490. }
  1491. /**
  1492. * Add document.body node
  1493. */
  1494. function addBodyNode() {
  1495. if (document.documentElement) {
  1496. return addRootNode(document.documentElement);
  1497. }
  1498. nodes.push({
  1499. node: function () {
  1500. return document.documentElement;
  1501. },
  1502. });
  1503. }
  1504. /**
  1505. * Remove root node
  1506. */
  1507. function removeRootNode(root) {
  1508. nodes = nodes.filter(function (node) { return root !== node &&
  1509. root !== (typeof node.node === 'function' ? node.node() : node.node); });
  1510. }
  1511. /**
  1512. * Get list of root nodes
  1513. */
  1514. function listRootNodes() {
  1515. return nodes;
  1516. }
  1517. /**
  1518. * Execute function when DOM is ready
  1519. */
  1520. function onReady(callback) {
  1521. var doc = document;
  1522. if (doc.readyState && doc.readyState !== 'loading') {
  1523. callback();
  1524. }
  1525. else {
  1526. doc.addEventListener('DOMContentLoaded', callback);
  1527. }
  1528. }
  1529. /**
  1530. * Callback
  1531. */
  1532. var callback = null;
  1533. /**
  1534. * Parameters for mutation observer
  1535. */
  1536. var observerParams = {
  1537. childList: true,
  1538. subtree: true,
  1539. attributes: true,
  1540. };
  1541. /**
  1542. * Queue DOM scan
  1543. */
  1544. function queueScan(node) {
  1545. if (!node.observer) {
  1546. return;
  1547. }
  1548. var observer = node.observer;
  1549. if (!observer.pendingScan) {
  1550. observer.pendingScan = setTimeout(function () {
  1551. delete observer.pendingScan;
  1552. if (callback) {
  1553. callback(node);
  1554. }
  1555. });
  1556. }
  1557. }
  1558. /**
  1559. * Check mutations for added nodes
  1560. */
  1561. function checkMutations(node, mutations) {
  1562. if (!node.observer) {
  1563. return;
  1564. }
  1565. var observer = node.observer;
  1566. if (!observer.pendingScan) {
  1567. for (var i = 0; i < mutations.length; i++) {
  1568. var item = mutations[i];
  1569. if (
  1570. // Check for added nodes
  1571. (item.addedNodes && item.addedNodes.length > 0) ||
  1572. // Check for icon or placeholder with modified attributes
  1573. (item.type === 'attributes' &&
  1574. item.target[elementDataProperty] !==
  1575. void 0)) {
  1576. if (!observer.paused) {
  1577. queueScan(node);
  1578. }
  1579. return;
  1580. }
  1581. }
  1582. }
  1583. }
  1584. /**
  1585. * Start/resume observer
  1586. */
  1587. function continueObserving(node, root) {
  1588. node.observer.instance.observe(root, observerParams);
  1589. }
  1590. /**
  1591. * Start mutation observer
  1592. */
  1593. function startObserver(node) {
  1594. var observer = node.observer;
  1595. if (observer && observer.instance) {
  1596. // Already started
  1597. return;
  1598. }
  1599. var root = typeof node.node === 'function' ? node.node() : node.node;
  1600. if (!root || !window) {
  1601. // document.body is not available yet or window is missing
  1602. return;
  1603. }
  1604. if (!observer) {
  1605. observer = {
  1606. paused: 0,
  1607. };
  1608. node.observer = observer;
  1609. }
  1610. // Create new instance, observe
  1611. observer.instance = new window.MutationObserver(checkMutations.bind(null, node));
  1612. continueObserving(node, root);
  1613. // Scan immediately
  1614. if (!observer.paused) {
  1615. queueScan(node);
  1616. }
  1617. }
  1618. /**
  1619. * Start all observers
  1620. */
  1621. function startObservers() {
  1622. listRootNodes().forEach(startObserver);
  1623. }
  1624. /**
  1625. * Stop observer
  1626. */
  1627. function stopObserver(node) {
  1628. if (!node.observer) {
  1629. return;
  1630. }
  1631. var observer = node.observer;
  1632. // Stop scan
  1633. if (observer.pendingScan) {
  1634. clearTimeout(observer.pendingScan);
  1635. delete observer.pendingScan;
  1636. }
  1637. // Disconnect observer
  1638. if (observer.instance) {
  1639. observer.instance.disconnect();
  1640. delete observer.instance;
  1641. }
  1642. }
  1643. /**
  1644. * Start observer when DOM is ready
  1645. */
  1646. function initObserver(cb) {
  1647. var isRestart = callback !== null;
  1648. if (callback !== cb) {
  1649. // Change callback and stop all pending observers
  1650. callback = cb;
  1651. if (isRestart) {
  1652. listRootNodes().forEach(stopObserver);
  1653. }
  1654. }
  1655. if (isRestart) {
  1656. // Restart instances
  1657. startObservers();
  1658. return;
  1659. }
  1660. // Start observers when document is ready
  1661. onReady(startObservers);
  1662. }
  1663. /**
  1664. * Pause observing node
  1665. */
  1666. function pauseObservingNode(node) {
  1667. (node ? [node] : listRootNodes()).forEach(function (node) {
  1668. if (!node.observer) {
  1669. node.observer = {
  1670. paused: 1,
  1671. };
  1672. return;
  1673. }
  1674. var observer = node.observer;
  1675. observer.paused++;
  1676. if (observer.paused > 1 || !observer.instance) {
  1677. return;
  1678. }
  1679. // Disconnect observer
  1680. var instance = observer.instance;
  1681. // checkMutations(node, instance.takeRecords());
  1682. instance.disconnect();
  1683. });
  1684. }
  1685. /**
  1686. * Pause observer
  1687. */
  1688. function pauseObserver(root) {
  1689. if (root) {
  1690. var node = findRootNode(root);
  1691. if (node) {
  1692. pauseObservingNode(node);
  1693. }
  1694. }
  1695. else {
  1696. pauseObservingNode();
  1697. }
  1698. }
  1699. /**
  1700. * Resume observer
  1701. */
  1702. function resumeObservingNode(observer) {
  1703. (observer ? [observer] : listRootNodes()).forEach(function (node) {
  1704. if (!node.observer) {
  1705. // Start observer
  1706. startObserver(node);
  1707. return;
  1708. }
  1709. var observer = node.observer;
  1710. if (observer.paused) {
  1711. observer.paused--;
  1712. if (!observer.paused) {
  1713. // Start / resume
  1714. var root = typeof node.node === 'function' ? node.node() : node.node;
  1715. if (!root) {
  1716. return;
  1717. }
  1718. else if (observer.instance) {
  1719. continueObserving(node, root);
  1720. }
  1721. else {
  1722. startObserver(node);
  1723. }
  1724. }
  1725. }
  1726. });
  1727. }
  1728. /**
  1729. * Resume observer
  1730. */
  1731. function resumeObserver(root) {
  1732. if (root) {
  1733. var node = findRootNode(root);
  1734. if (node) {
  1735. resumeObservingNode(node);
  1736. }
  1737. }
  1738. else {
  1739. resumeObservingNode();
  1740. }
  1741. }
  1742. /**
  1743. * Observe node
  1744. */
  1745. function observe(root, autoRemove) {
  1746. if ( autoRemove === void 0 ) autoRemove = false;
  1747. var node = addRootNode(root, autoRemove);
  1748. startObserver(node);
  1749. return node;
  1750. }
  1751. /**
  1752. * Remove observed node
  1753. */
  1754. function stopObserving(root) {
  1755. var node = findRootNode(root);
  1756. if (node) {
  1757. stopObserver(node);
  1758. removeRootNode(root);
  1759. }
  1760. }
  1761. /**
  1762. * Compare props
  1763. */
  1764. function propsChanged(props1, props2) {
  1765. if (props1.name !== props2.name || props1.mode !== props2.mode) {
  1766. return true;
  1767. }
  1768. var customisations1 = props1.customisations;
  1769. var customisations2 = props2.customisations;
  1770. for (var key in defaultExtendedIconCustomisations) {
  1771. if (customisations1[key] !== customisations2[key]) {
  1772. return true;
  1773. }
  1774. }
  1775. return false;
  1776. }
  1777. function rotateFromString(value, defaultValue) {
  1778. if ( defaultValue === void 0 ) defaultValue = 0;
  1779. var units = value.replace(/^-?[0-9.]*/, "");
  1780. function cleanup(value2) {
  1781. while (value2 < 0) {
  1782. value2 += 4;
  1783. }
  1784. return value2 % 4;
  1785. }
  1786. if (units === "") {
  1787. var num = parseInt(value);
  1788. return isNaN(num) ? 0 : cleanup(num);
  1789. } else if (units !== value) {
  1790. var split = 0;
  1791. switch (units) {
  1792. case "%":
  1793. split = 25;
  1794. break;
  1795. case "deg":
  1796. split = 90;
  1797. }
  1798. if (split) {
  1799. var num$1 = parseFloat(value.slice(0, value.length - units.length));
  1800. if (isNaN(num$1)) {
  1801. return 0;
  1802. }
  1803. num$1 = num$1 / split;
  1804. return num$1 % 1 === 0 ? cleanup(num$1) : 0;
  1805. }
  1806. }
  1807. return defaultValue;
  1808. }
  1809. var separator = /[\s,]+/;
  1810. function flipFromString(custom, flip) {
  1811. flip.split(separator).forEach(function (str) {
  1812. var value = str.trim();
  1813. switch (value) {
  1814. case "horizontal":
  1815. custom.hFlip = true;
  1816. break;
  1817. case "vertical":
  1818. custom.vFlip = true;
  1819. break;
  1820. }
  1821. });
  1822. }
  1823. /**
  1824. * Size attributes
  1825. */
  1826. var sizeAttributes = ['width', 'height'];
  1827. /**
  1828. * Boolean attributes
  1829. */
  1830. var booleanAttributes = [
  1831. 'inline',
  1832. 'hFlip',
  1833. 'vFlip' ];
  1834. /**
  1835. * Get attribute value
  1836. */
  1837. function getBooleanAttribute(value, key) {
  1838. if (value === key || value === 'true') {
  1839. return true;
  1840. }
  1841. if (value === '' || value === 'false') {
  1842. return false;
  1843. }
  1844. return null;
  1845. }
  1846. /**
  1847. * Get element properties from HTML element
  1848. */
  1849. function getElementProps(element) {
  1850. // Get icon name
  1851. var name = element.getAttribute('data-icon');
  1852. var icon = typeof name === 'string' && stringToIcon(name, true);
  1853. if (!icon) {
  1854. return null;
  1855. }
  1856. // Get defaults and inline
  1857. var customisations = Object.assign({}, defaultExtendedIconCustomisations,
  1858. {inline: element.classList && element.classList.contains(inlineClass)});
  1859. // Get dimensions
  1860. sizeAttributes.forEach(function (attr) {
  1861. var value = element.getAttribute('data-' + attr);
  1862. if (value) {
  1863. customisations[attr] = value;
  1864. }
  1865. });
  1866. // Get rotation
  1867. var rotation = element.getAttribute('data-rotate');
  1868. if (typeof rotation === 'string') {
  1869. customisations.rotate = rotateFromString(rotation);
  1870. }
  1871. // Get flip shorthand
  1872. var flip = element.getAttribute('data-flip');
  1873. if (typeof flip === 'string') {
  1874. flipFromString(customisations, flip);
  1875. }
  1876. // Boolean attributes
  1877. booleanAttributes.forEach(function (attr) {
  1878. var key = 'data-' + attr;
  1879. var value = getBooleanAttribute(element.getAttribute(key), key);
  1880. if (typeof value === 'boolean') {
  1881. customisations[attr] = value;
  1882. }
  1883. });
  1884. // Get render mode. Not checking actual value because incorrect values are treated as inline
  1885. var mode = element.getAttribute('data-mode');
  1886. return {
  1887. name: name,
  1888. icon: icon,
  1889. customisations: customisations,
  1890. mode: mode,
  1891. };
  1892. }
  1893. /**
  1894. * Selector combining class names and tags
  1895. */
  1896. var selector = 'svg.' +
  1897. blockClass +
  1898. ', i.' +
  1899. blockClass +
  1900. ', span.' +
  1901. blockClass +
  1902. ', i.' +
  1903. inlineClass +
  1904. ', span.' +
  1905. inlineClass;
  1906. /**
  1907. * Find all parent nodes in DOM
  1908. */
  1909. function scanRootNode(root) {
  1910. var nodes = [];
  1911. root.querySelectorAll(selector).forEach(function (node) {
  1912. // Get props, ignore SVG rendered outside of SVG framework
  1913. var props = node[elementDataProperty] || node.tagName.toLowerCase() !== 'svg'
  1914. ? getElementProps(node)
  1915. : null;
  1916. if (props) {
  1917. nodes.push({
  1918. node: node,
  1919. props: props,
  1920. });
  1921. }
  1922. });
  1923. return nodes;
  1924. }
  1925. function iconToHTML(body, attributes) {
  1926. var renderAttribsHTML = body.indexOf("xlink:") === -1 ? "" : ' xmlns:xlink="http://www.w3.org/1999/xlink"';
  1927. for (var attr in attributes) {
  1928. renderAttribsHTML += " " + attr + '="' + attributes[attr] + '"';
  1929. }
  1930. return '<svg xmlns="http://www.w3.org/2000/svg"' + renderAttribsHTML + ">" + body + "</svg>";
  1931. }
  1932. /**
  1933. * Get classes to add from icon name
  1934. */
  1935. function iconClasses(iconName) {
  1936. var classesToAdd = new Set(['iconify']);
  1937. ['provider', 'prefix'].forEach(function (attr) {
  1938. if (iconName[attr]) {
  1939. classesToAdd.add('iconify--' + iconName[attr]);
  1940. }
  1941. });
  1942. return classesToAdd;
  1943. }
  1944. /**
  1945. * Add classes to SVG, removing previously added classes, keeping custom classes
  1946. */
  1947. function applyClasses(svg, classes, previouslyAddedClasses, placeholder) {
  1948. var svgClasses = svg.classList;
  1949. // Copy classes from placeholder
  1950. if (placeholder) {
  1951. var placeholderClasses = placeholder.classList;
  1952. Array.from(placeholderClasses).forEach(function (item) {
  1953. svgClasses.add(item);
  1954. });
  1955. }
  1956. // Add new classes
  1957. var addedClasses = [];
  1958. classes.forEach(function (item) {
  1959. if (!svgClasses.contains(item)) {
  1960. // Add new class
  1961. svgClasses.add(item);
  1962. addedClasses.push(item);
  1963. }
  1964. else if (previouslyAddedClasses.has(item)) {
  1965. // Was added before: keep it
  1966. addedClasses.push(item);
  1967. }
  1968. });
  1969. // Remove previously added classes
  1970. previouslyAddedClasses.forEach(function (item) {
  1971. if (!classes.has(item)) {
  1972. // Class that was added before, but no longer needed
  1973. svgClasses.remove(item);
  1974. }
  1975. });
  1976. return addedClasses;
  1977. }
  1978. /**
  1979. * Copy old styles, apply new styles
  1980. */
  1981. function applyStyle(svg, styles, previouslyAddedStyles) {
  1982. var svgStyle = svg.style;
  1983. // Remove previously added styles
  1984. (previouslyAddedStyles || []).forEach(function (prop) {
  1985. svgStyle.removeProperty(prop);
  1986. });
  1987. // Apply new styles, ignoring styles that already exist
  1988. var appliedStyles = [];
  1989. for (var prop in styles) {
  1990. if (!svgStyle.getPropertyValue(prop)) {
  1991. appliedStyles.push(prop);
  1992. svgStyle.setProperty(prop, styles[prop]);
  1993. }
  1994. }
  1995. return appliedStyles;
  1996. }
  1997. /**
  1998. * Render icon as inline SVG
  1999. */
  2000. function renderInlineSVG(element, props, iconData) {
  2001. // Create placeholder. Why placeholder? innerHTML setter on SVG does not work in some environments.
  2002. var span;
  2003. try {
  2004. span = document.createElement('span');
  2005. }
  2006. catch (err) {
  2007. return element;
  2008. }
  2009. // Generate data to render
  2010. var customisations = props.customisations;
  2011. var renderData = iconToSVG(iconData, customisations);
  2012. // Get old data
  2013. var oldData = element[elementDataProperty];
  2014. // Generate SVG
  2015. var html = iconToHTML(replaceIDs(renderData.body), Object.assign({}, {'aria-hidden': 'true',
  2016. 'role': 'img'},
  2017. renderData.attributes));
  2018. span.innerHTML = html;
  2019. // Get SVG element
  2020. var svg = span.childNodes[0];
  2021. // Add attributes
  2022. var placeholderAttributes = element.attributes;
  2023. for (var i = 0; i < placeholderAttributes.length; i++) {
  2024. var item = placeholderAttributes.item(i);
  2025. var name = item.name;
  2026. if (name !== 'class' && !svg.hasAttribute(name)) {
  2027. svg.setAttribute(name, item.value);
  2028. }
  2029. }
  2030. // Add classes
  2031. var classesToAdd = iconClasses(props.icon);
  2032. var addedClasses = applyClasses(svg, classesToAdd, new Set(oldData && oldData.addedClasses), element);
  2033. // Update style
  2034. var addedStyles = applyStyle(svg, customisations.inline
  2035. ? {
  2036. 'vertical-align': '-0.125em',
  2037. }
  2038. : {}, oldData && oldData.addedStyles);
  2039. // Add data to element
  2040. var newData = Object.assign({}, props,
  2041. {status: 'loaded',
  2042. addedClasses: addedClasses,
  2043. addedStyles: addedStyles});
  2044. svg[elementDataProperty] = newData;
  2045. // Replace old element
  2046. if (element.parentNode) {
  2047. element.parentNode.replaceChild(svg, element);
  2048. }
  2049. return svg;
  2050. }
  2051. function encodeSVGforURL(svg) {
  2052. return svg.replace(/"/g, "'").replace(/%/g, "%25").replace(/#/g, "%23").replace(/</g, "%3C").replace(/>/g, "%3E").replace(/\s+/g, " ");
  2053. }
  2054. function svgToURL(svg) {
  2055. return 'url("data:image/svg+xml,' + encodeSVGforURL(svg) + '")';
  2056. }
  2057. var commonProps = {
  2058. display: 'inline-block',
  2059. };
  2060. var monotoneProps = {
  2061. 'background-color': 'currentColor',
  2062. };
  2063. var coloredProps = {
  2064. 'background-color': 'transparent',
  2065. };
  2066. // Dynamically add common props to variables above
  2067. var propsToAdd = {
  2068. image: 'var(--svg)',
  2069. repeat: 'no-repeat',
  2070. size: '100% 100%',
  2071. };
  2072. var propsToAddTo = {
  2073. '-webkit-mask': monotoneProps,
  2074. 'mask': monotoneProps,
  2075. 'background': coloredProps,
  2076. };
  2077. for (var prefix in propsToAddTo) {
  2078. var list = propsToAddTo[prefix];
  2079. for (var prop in propsToAdd) {
  2080. list[prefix + '-' + prop] = propsToAdd[prop];
  2081. }
  2082. }
  2083. /**
  2084. * Fix size: add 'px' to numbers
  2085. */
  2086. function fixSize(value) {
  2087. return value + (value.match(/^[-0-9.]+$/) ? 'px' : '');
  2088. }
  2089. /**
  2090. * Render icon as inline SVG
  2091. */
  2092. function renderBackground(element, props, iconData, useMask) {
  2093. // Generate data to render
  2094. var customisations = props.customisations;
  2095. var renderData = iconToSVG(iconData, customisations);
  2096. var renderAttribs = renderData.attributes;
  2097. // Get old data
  2098. var oldData = element[elementDataProperty];
  2099. // Generate SVG
  2100. var html = iconToHTML(renderData.body, Object.assign({}, renderAttribs,
  2101. {width: iconData.width + '',
  2102. height: iconData.height + ''}));
  2103. // Add classes
  2104. var classesToAdd = iconClasses(props.icon);
  2105. var addedClasses = applyClasses(element, classesToAdd, new Set(oldData && oldData.addedClasses));
  2106. // Update style
  2107. var url = svgToURL(html);
  2108. var newStyles = Object.assign({}, {'--svg': url,
  2109. 'width': fixSize(renderAttribs.width),
  2110. 'height': fixSize(renderAttribs.height)},
  2111. commonProps,
  2112. (useMask ? monotoneProps : coloredProps));
  2113. if (customisations.inline) {
  2114. newStyles['vertical-align'] = '-0.125em';
  2115. }
  2116. var addedStyles = applyStyle(element, newStyles, oldData && oldData.addedStyles);
  2117. // Add data to element
  2118. var newData = Object.assign({}, props,
  2119. {status: 'loaded',
  2120. addedClasses: addedClasses,
  2121. addedStyles: addedStyles});
  2122. element[elementDataProperty] = newData;
  2123. return element;
  2124. }
  2125. /**
  2126. * Flag to avoid scanning DOM too often
  2127. */
  2128. var scanQueued = false;
  2129. /**
  2130. * Icons have been loaded
  2131. */
  2132. function checkPendingIcons() {
  2133. if (!scanQueued) {
  2134. scanQueued = true;
  2135. setTimeout(function () {
  2136. if (scanQueued) {
  2137. scanQueued = false;
  2138. scanDOM();
  2139. }
  2140. });
  2141. }
  2142. }
  2143. /**
  2144. * Scan node for placeholders
  2145. */
  2146. function scanDOM(rootNode, addTempNode) {
  2147. if ( addTempNode === void 0 ) addTempNode = false;
  2148. // List of icons to load: [provider][prefix] = Set<name>
  2149. var iconsToLoad = Object.create(null);
  2150. function getIcon(icon, load) {
  2151. var provider = icon.provider;
  2152. var prefix = icon.prefix;
  2153. var name = icon.name;
  2154. var storage = getStorage(provider, prefix);
  2155. var storedIcon = storage.icons[name];
  2156. if (storedIcon) {
  2157. return {
  2158. status: 'loaded',
  2159. icon: storedIcon,
  2160. };
  2161. }
  2162. if (storage.missing.has(name)) {
  2163. return {
  2164. status: 'missing',
  2165. };
  2166. }
  2167. if (load && !isPending(icon)) {
  2168. var providerIconsToLoad = iconsToLoad[provider] ||
  2169. (iconsToLoad[provider] = Object.create(null));
  2170. var set = providerIconsToLoad[prefix] ||
  2171. (providerIconsToLoad[prefix] = new Set());
  2172. set.add(name);
  2173. }
  2174. return {
  2175. status: 'loading',
  2176. };
  2177. }
  2178. // Parse all root nodes
  2179. (rootNode ? [rootNode] : listRootNodes()).forEach(function (observedNode) {
  2180. var root = typeof observedNode.node === 'function'
  2181. ? observedNode.node()
  2182. : observedNode.node;
  2183. if (!root || !root.querySelectorAll) {
  2184. return;
  2185. }
  2186. // Track placeholders
  2187. var hasPlaceholders = false;
  2188. // Observer
  2189. var paused = false;
  2190. /**
  2191. * Render icon
  2192. */
  2193. function render(element, props, iconData) {
  2194. if (!paused) {
  2195. paused = true;
  2196. pauseObservingNode(observedNode);
  2197. }
  2198. if (element.tagName.toUpperCase() !== 'SVG') {
  2199. // Check for one of style modes
  2200. var mode = props.mode;
  2201. var isMask = mode === 'mask' ||
  2202. (mode === 'bg'
  2203. ? false
  2204. : mode === 'style'
  2205. ? iconData.body.indexOf('currentColor') !== -1
  2206. : null);
  2207. if (typeof isMask === 'boolean') {
  2208. renderBackground(element, props, Object.assign({}, defaultIconProps,
  2209. iconData), isMask);
  2210. return;
  2211. }
  2212. }
  2213. renderInlineSVG(element, props, iconData);
  2214. }
  2215. // Find all elements
  2216. scanRootNode(root).forEach(function (ref) {
  2217. var node = ref.node;
  2218. var props = ref.props;
  2219. // Check if item already has props
  2220. var oldData = node[elementDataProperty];
  2221. if (!oldData) {
  2222. // New icon without data
  2223. var ref$1 = getIcon(props.icon, true);
  2224. var status = ref$1.status;
  2225. var icon = ref$1.icon;
  2226. if (icon) {
  2227. // Ready to render!
  2228. render(node, props, icon);
  2229. return;
  2230. }
  2231. // Loading or missing
  2232. hasPlaceholders = hasPlaceholders || status === 'loading';
  2233. node[elementDataProperty] = Object.assign({}, props,
  2234. {status: status});
  2235. return;
  2236. }
  2237. // Previously found icon
  2238. var item;
  2239. if (!propsChanged(oldData, props)) {
  2240. // Props have not changed. Check status
  2241. var oldStatus = oldData.status;
  2242. if (oldStatus !== 'loading') {
  2243. return;
  2244. }
  2245. item = getIcon(props.icon, false);
  2246. if (!item.icon) {
  2247. // Nothing to render
  2248. oldData.status = item.status;
  2249. return;
  2250. }
  2251. }
  2252. else {
  2253. // Properties have changed: load icon if name has changed
  2254. item = getIcon(props.icon, oldData.name !== props.name);
  2255. if (!item.icon) {
  2256. // Cannot render icon: update status and props
  2257. hasPlaceholders =
  2258. hasPlaceholders || item.status === 'loading';
  2259. Object.assign(oldData, Object.assign({}, props,
  2260. {status: item.status}));
  2261. return;
  2262. }
  2263. }
  2264. // Re-render icon
  2265. render(node, props, item.icon);
  2266. });
  2267. // Observed node stuff
  2268. if (observedNode.temporary && !hasPlaceholders) {
  2269. // Remove temporary node
  2270. stopObserving(root);
  2271. }
  2272. else if (addTempNode && hasPlaceholders) {
  2273. // Add new temporary node
  2274. observe(root, true);
  2275. }
  2276. else if (paused && observedNode.observer) {
  2277. // Resume observer
  2278. resumeObservingNode(observedNode);
  2279. }
  2280. });
  2281. // Load icons
  2282. var loop = function ( provider ) {
  2283. var providerIconsToLoad = iconsToLoad[provider];
  2284. var loop$1 = function ( prefix ) {
  2285. var set = providerIconsToLoad[prefix];
  2286. loadIcons(Array.from(set).map(function (name) { return ({
  2287. provider: provider,
  2288. prefix: prefix,
  2289. name: name,
  2290. }); }), checkPendingIcons);
  2291. };
  2292. for (var prefix in providerIconsToLoad) loop$1( prefix );
  2293. };
  2294. for (var provider in iconsToLoad) loop( provider );
  2295. }
  2296. /**
  2297. * Scan node for placeholders
  2298. */
  2299. function scanElement(root) {
  2300. // Add temporary node
  2301. var node = findRootNode(root);
  2302. if (!node) {
  2303. scanDOM({
  2304. node: root,
  2305. temporary: true,
  2306. }, true);
  2307. }
  2308. else {
  2309. scanDOM(node);
  2310. }
  2311. }
  2312. function generateIcon(name, customisations, returnString) {
  2313. if ( returnString === void 0 ) returnString = false;
  2314. // Get icon data
  2315. var iconData = getIconData(name);
  2316. if (!iconData) {
  2317. return null;
  2318. }
  2319. // Split name
  2320. var iconName = stringToIcon(name);
  2321. // Clean up customisations
  2322. var changes = mergeCustomisations(defaultExtendedIconCustomisations, customisations || {});
  2323. // Get data
  2324. var result = renderInlineSVG(document.createElement('span'), {
  2325. name: name,
  2326. icon: iconName,
  2327. customisations: changes,
  2328. }, iconData);
  2329. return returnString
  2330. ? result.outerHTML
  2331. : result;
  2332. }
  2333. /**
  2334. * Get version
  2335. */
  2336. function getVersion() {
  2337. return '3.1.0';
  2338. }
  2339. /**
  2340. * Generate SVG element
  2341. */
  2342. function renderSVG(name, customisations) {
  2343. return generateIcon(name, customisations, false);
  2344. }
  2345. /**
  2346. * Generate SVG as string
  2347. */
  2348. function renderHTML(name, customisations) {
  2349. return generateIcon(name, customisations, true);
  2350. }
  2351. /**
  2352. * Get rendered icon as object that can be used to create SVG (use replaceIDs on body)
  2353. */
  2354. function renderIcon(name, customisations) {
  2355. // Get icon data
  2356. var iconData = getIconData(name);
  2357. if (!iconData) {
  2358. return null;
  2359. }
  2360. // Clean up customisations
  2361. var changes = mergeCustomisations(defaultExtendedIconCustomisations, customisations || {});
  2362. // Get data
  2363. return iconToSVG(iconData, changes);
  2364. }
  2365. /**
  2366. * Scan DOM
  2367. */
  2368. function scan(root) {
  2369. if (root) {
  2370. scanElement(root);
  2371. }
  2372. else {
  2373. scanDOM();
  2374. }
  2375. }
  2376. /**
  2377. * Initialise stuff
  2378. */
  2379. if (typeof document !== 'undefined' && typeof window !== 'undefined') {
  2380. // Add document.body node
  2381. addBodyNode();
  2382. var _window$1 = window;
  2383. // Load icons from global "IconifyPreload"
  2384. if (_window$1.IconifyPreload !== void 0) {
  2385. var preload = _window$1.IconifyPreload;
  2386. var err$1 = 'Invalid IconifyPreload syntax.';
  2387. if (typeof preload === 'object' && preload !== null) {
  2388. (preload instanceof Array ? preload : [preload]).forEach(function (item) {
  2389. try {
  2390. if (
  2391. // Check if item is an object and not null/array
  2392. typeof item !== 'object' ||
  2393. item === null ||
  2394. item instanceof Array ||
  2395. // Check for 'icons' and 'prefix'
  2396. typeof item.icons !== 'object' ||
  2397. typeof item.prefix !== 'string' ||
  2398. // Add icon set
  2399. !addCollection(item)) {
  2400. console.error(err$1);
  2401. }
  2402. }
  2403. catch (e) {
  2404. console.error(err$1);
  2405. }
  2406. });
  2407. }
  2408. }
  2409. // Load observer and scan DOM on next tick
  2410. setTimeout(function () {
  2411. initObserver(scanDOM);
  2412. scanDOM();
  2413. });
  2414. }
  2415. /**
  2416. * Enable cache
  2417. */
  2418. function enableCache(storage, enable) {
  2419. toggleBrowserCache(storage, enable !== false);
  2420. }
  2421. /**
  2422. * Disable cache
  2423. */
  2424. function disableCache(storage) {
  2425. toggleBrowserCache(storage, true);
  2426. }
  2427. /**
  2428. * Initialise stuff
  2429. */
  2430. // Set API module
  2431. setAPIModule('', fetchAPIModule);
  2432. /**
  2433. * Browser stuff
  2434. */
  2435. if (typeof document !== 'undefined' && typeof window !== 'undefined') {
  2436. // Set cache and load existing cache
  2437. initBrowserStorage();
  2438. var _window = window;
  2439. // Set API from global "IconifyProviders"
  2440. if (_window.IconifyProviders !== void 0) {
  2441. var providers = _window.IconifyProviders;
  2442. if (typeof providers === 'object' && providers !== null) {
  2443. for (var key in providers) {
  2444. var err = 'IconifyProviders[' + key + '] is invalid.';
  2445. try {
  2446. var value = providers[key];
  2447. if (typeof value !== 'object' ||
  2448. !value ||
  2449. value.resources === void 0) {
  2450. continue;
  2451. }
  2452. if (!addAPIProvider(key, value)) {
  2453. console.error(err);
  2454. }
  2455. }
  2456. catch (e) {
  2457. console.error(err);
  2458. }
  2459. }
  2460. }
  2461. }
  2462. }
  2463. /**
  2464. * Internal API
  2465. */
  2466. var _api = {
  2467. getAPIConfig: getAPIConfig,
  2468. setAPIModule: setAPIModule,
  2469. sendAPIQuery: sendAPIQuery,
  2470. setFetch: setFetch,
  2471. getFetch: getFetch,
  2472. listAPIProviders: listAPIProviders,
  2473. };
  2474. /**
  2475. * Global variable
  2476. */
  2477. var Iconify = {
  2478. // IconifyAPIInternalFunctions
  2479. _api: _api,
  2480. // IconifyAPIFunctions
  2481. addAPIProvider: addAPIProvider,
  2482. loadIcons: loadIcons,
  2483. loadIcon: loadIcon,
  2484. // IconifyStorageFunctions
  2485. iconExists: iconExists,
  2486. getIcon: getIcon,
  2487. listIcons: listIcons,
  2488. addIcon: addIcon,
  2489. addCollection: addCollection,
  2490. // IconifyBuilderFunctions
  2491. replaceIDs: replaceIDs,
  2492. calculateSize: calculateSize,
  2493. buildIcon: iconToSVG,
  2494. // IconifyCommonFunctions
  2495. getVersion: getVersion,
  2496. renderSVG: renderSVG,
  2497. renderHTML: renderHTML,
  2498. renderIcon: renderIcon,
  2499. scan: scan,
  2500. observe: observe,
  2501. stopObserving: stopObserving,
  2502. pauseObserver: pauseObserver,
  2503. resumeObserver: resumeObserver,
  2504. // IconifyBrowserCacheFunctions
  2505. enableCache: enableCache,
  2506. disableCache: disableCache,
  2507. };
  2508. exports._api = _api;
  2509. exports.addAPIProvider = addAPIProvider;
  2510. exports.addCollection = addCollection;
  2511. exports.addIcon = addIcon;
  2512. exports.buildIcon = iconToSVG;
  2513. exports.calculateSize = calculateSize;
  2514. exports.default = Iconify;
  2515. exports.disableCache = disableCache;
  2516. exports.enableCache = enableCache;
  2517. exports.getIcon = getIcon;
  2518. exports.getVersion = getVersion;
  2519. exports.iconExists = iconExists;
  2520. exports.listIcons = listIcons;
  2521. exports.loadIcon = loadIcon;
  2522. exports.loadIcons = loadIcons;
  2523. exports.observe = observe;
  2524. exports.pauseObserver = pauseObserver;
  2525. exports.renderHTML = renderHTML;
  2526. exports.renderIcon = renderIcon;
  2527. exports.renderSVG = renderSVG;
  2528. exports.replaceIDs = replaceIDs;
  2529. exports.resumeObserver = resumeObserver;
  2530. exports.scan = scan;
  2531. exports.stopObserving = stopObserving;
  2532. Object.defineProperty(exports, '__esModule', { value: true });
  2533. return exports;
  2534. })({});
  2535. // Export as ES module
  2536. if (typeof exports === 'object') {
  2537. try {
  2538. exports.__esModule = true;
  2539. exports.default = Iconify;
  2540. for (var key in Iconify) {
  2541. exports[key] = Iconify[key];
  2542. }
  2543. } catch (err) {
  2544. }
  2545. }
  2546. // Export to window or web worker
  2547. try {
  2548. if (self.Iconify === void 0) {
  2549. self.Iconify = Iconify;
  2550. }
  2551. } catch (err) {
  2552. }