/*
** Copyright © 2025 The CTAN Team and individual authors
**
** This file is distributed under the 3-clause BSD license.
** See file LICENSE for details.
*/
/**
* The icons have logical names.
* To ensure a certain consistency the following list is sorted by icon name.
*/
const ICON = {
'attribute.account.account': 'mdi-account',
'page.account': 'mdi-account',
'entity.account': 'mdi-account',
'attribute.guestbook.account': 'mdi-account',
'attribute.upload.uploader': 'mdi-account-arrow-up-outline',
'attribute.upload.author': 'mdi-account-badge-outline',
'entity.author': 'mdi-account-badge-outline',
'attribute.author.key': 'mdi-account-badge-outline',
'attribute.account.roles': 'mdi-account-box',
'page.user.public': 'mdi-account-box-outline',
'page.admin.user-stops': 'mdi-account-cancel',
'button.author.confirm': 'mdi-account-check-outline',
'page.lugs': 'mdi-account-group',
'card.lugs': 'mdi-account-group',
'page.community': 'mdi-account-group-outline',
'item.team.former': 'mdi-account-hard-hat',
'item.team.member': 'mdi-account-hard-hat-outline',
'page.team': 'mdi-account-hard-hat-outline',
'role.admin': 'mdi-account-hard-hat-outline',
'account.unlocked': 'mdi-account-lock-open-outline',
'account.locked': 'mdi-account-lock-outline',
'button.pkg.orphaned': 'mdi-account-off',
'dialog.register': 'mdi-account-plus',
'dialog.reset': 'mdi-account-question',
'button.account.delete': 'mdi-account-remove',
'attribute.cdn.contact': 'mdi-account-network-outline',
'button.user.settings': 'mdi-account-settings',
'page.admin.users': 'mdi-account-wrench',
'info.error': 'mdi-alert-octagon-outline',
'info.passwd.fail': 'mdi-alert-octagon-outline',
'license.type.nonfree': 'mdi-alert-rhombus-outline',
'section.note': 'mdi-alert-rhombus-outline',
'page.api': 'mdi-api',
'section.pkg.docs.source': 'mdi-archive',
'entity.archive-notes': 'mdi-archive-outline',
'button.pkg.docs.src': 'mdi-archive-outline',
'file.ext.arc': 'mdi-archive-outline',
'file.ext.boo': 'mdi-archive-outline',
'file.ext.gz': 'mdi-archive-outline',
'file.ext.hqx': 'mdi-archive-outline',
'file.ext.xz': 'mdi-archive-outline',
'file.ext.zip': 'mdi-archive-outline',
'button.backward': 'mdi-arrow-left',
'button.back': 'mdi-arrow-left-bold',
'button.foreward': 'mdi-arrow-right',
'button.visit': 'mdi-arrow-top-right-bold-outline',
'file.type.l': 'mdi-arrow-u-right-bottom',
'gender.x': 'mdi-baby-face-outline',
'attribute.account.name': 'mdi-badge-account-outline',
'tab.pkg.summary': 'mdi-book',
'page.admin.guestbook': 'mdi-book-account-outline',
'page.admin.guestbook.stops': 'mdi-book-cancel-outline',
'page.help.ctan': 'mdi-book-open-page-variant-outline',
'tab.my.pages': 'mdi-book-open-variant',
'page.browse': 'mdi-bookshelf',
'tab.pkg.docs': 'mdi-bookshelf',
'attribute.pkg.bugs': 'mdi-bug-outline',
'attribute.upload.bugs': 'mdi-bug-outline',
'attribute.message.to': 'mdi-calendar-end-outline',
'attribute.upload.created': 'mdi-calendar-outline',
'attribute.upload.updated': 'mdi-calendar-outline',
'attribute.account.created': 'mdi-calendar-start-outline',
'attribute.guestbook.created': 'mdi-calendar-start-outline',
'attribute.message.from': 'mdi-calendar-start-outline',
'page.my.data': 'mdi-card-account-details-outline',
'tab.my.data': 'mdi-card-account-details-outline',
'page.my.packages': 'mdi-card-multiple-outline',
'tab.my.packages': 'mdi-card-multiple-outline',
'page.packages': 'mdi-card-multiple-outline',
'tab.packages': 'mdi-card-multiple-outline',
'label.pkg.bibtex.key': 'mdi-card-text',
'attribute.upload.description': 'mdi-card-text',
'attribute.guestbook.text': 'mdi-card-text-outline',
'attribute.upload.summary': 'mdi-card-text-outline',
'tab.pkg.abstract': 'mdi-card-text-outline',
'attribute.rating.comment': 'mdi-card-text-outline',
'attribute.rating.expertise': 'mdi-certificate-outline',
'card.statistics.upload': 'mdi-chart-box-outline',
'state.ok': 'mdi-check',
'account.enabled.true': 'mdi-check-circle-outline',
'page.cdn.monitor': 'mdi-check-network-outline',
'checkbox.off': 'mdi-checkbox-blank-outline',
'checkbox.on': 'mdi-checkbox-marked-outline',
'breadcrumb.sep': 'mdi-chevron-right',
'expertise.full': 'mdi-circle',
'carousel.delimiter': 'mdi-circle-double',
'page.item': 'mdi-circle-medium',
'expertise.empty': 'mdi-circle-outline',
'animation.0': 'mdi-circle-outline',
'animation.1': 'mdi-circle-slice-2',
'animation.2': 'mdi-circle-slice-4',
'animation.3': 'mdi-circle-slice-6',
'attribute.account.city': 'mdi-city',
'attribute.cdn.city': 'mdi-city',
'markdown.input': 'mdi-clipboard-edit-outline',
'page.admin.jobs': 'mdi-clock-start',
'button.clear': 'mdi-close',
'button.close': 'mdi-close',
'attribute.stopword.word': 'mdi-close-octagon-outline',
'section.json': 'mdi-code-json',
'markdown.tab.source': 'mdi-code-tags',
'page.admin': 'mdi-cogs',
'attribute.upload.note': 'mdi-comment-outline',
'attribute.guestbook.title': 'mdi-comment-alert',
'section.ratings.all': 'mdi-comment-multiple-outline',
'section.ratings.my': 'mdi-comment-outline',
'button.guestbook.add': 'mdi-comment-plus-outline',
'dialog.guestbook.add': 'mdi-comment-plus-outline',
'attribute.guestbook.comment': 'mdi-comment-text',
'page.guestbook': 'mdi-comment-text-multiple-outline',
'attribute.guestbook.section': 'mdi-comment-text-outline',
'button.save': 'mdi-content-save-outline',
'attribute.pkg.repository': 'mdi-database-outline',
'attribute.upload.repository': 'mdi-database-outline',
'button.delete': 'mdi-delete-outline',
'card.dvd': 'mdi-disc',
'tab.pkg.install.mactex': 'mdi-disc',
'tab.pkg.install.miktex': 'mdi-disc',
'tab.pkg.install.texlive': 'mdi-disc',
'button.settings': 'mdi-dots-vertical',
'button.download': 'mdi-download',
'tab.download': 'mdi-download',
'tab.pkg.install.download': 'mdi-download',
'tab.pkg.install': 'mdi-download',
'card.distribution.intro': 'mdi-download',
'card.distribution.mactex': 'mdi-download',
'card.distribution.miktex': 'mdi-download',
'card.distribution.texlive': 'mdi-download',
'attribute.cdn.region': 'mdi-earth',
'attribute.upload.notify': 'mdi-email-check',
'button.feedback': 'mdi-email-fast',
'page.admin.notifications': 'mdi-email-fast-outline',
'page.contact': 'mdi-email-fast-outline',
'attribute.lug.newsletter': 'mdi-email-multiple-outline',
'attribute.upload.mailinglist': 'mdi-email-newsletter',
'tab.pkg.announce': 'mdi-email-newsletter',
'attribute.account.email': 'mdi-email-outline',
'attribute.email': 'mdi-email-outline',
'attribute.guestbook.email': 'mdi-email-outline',
'attribute.lug.email': 'mdi-email-outline',
'attribute.cdn.email': 'mdi-email-outline',
'attribute.upload.email': 'mdi-email-outline',
'dialog.register-ack': 'mdi-email-outline',
'state.error': 'mdi-exclamation-thick',
'button.password.show': 'mdi-eye-outline',
'field.view': 'mdi-eye-outline',
'button.password.hide': 'mdi-eye-off-outline',
'button.view.settings': 'mdi-eye-settings-outline',
'file.type.x': 'mdi-file',
'file.ext.html': 'mdi-file-code-outline',
'file.name.makefile': 'mdi-file-cog',
'file.name.Makefile': 'mdi-file-cog',
'file.ext.bst': 'mdi-file-cog-outline',
'file.ext.cls': 'mdi-file-cog-outline',
'file.ext.dtx': 'mdi-file-cog-outline',
'file.ext.ist': 'mdi-file-cog-outline',
'file.ext.sty': 'mdi-file-cog-outline',
'file.ext.dvi': 'mdi-file-document',
'file.ext.pdf': 'mdi-file-document',
'file.ext.ps': 'mdi-file-document',
'file.ext.tex': 'mdi-file-document',
'file.ext.latex': 'mdi-file-document-outline',
'file.ext.ltx': 'mdi-file-document-outline',
'file.ext.tex': 'mdi-file-document-outline',
'tab.pkg.bibtex': 'mdi-file-document-outline',
'file.ext.eps': 'mdi-file-image-outline',
'file.ext.gif': 'mdi-file-image-outline',
'file.ext.jpeg': 'mdi-file-image-outline',
'file.ext.jpg': 'mdi-file-image-outline',
'file.ext.png': 'mdi-file-image-outline',
'file.ext.tif': 'mdi-file-image-outline',
'page.help.lion.files': 'mdi-file-image-outline',
'tab.files': 'mdi-file-multiple-outline', //
'file.type.f': 'mdi-file-outline',
'field.pkg.bibtex.type': 'mdi-file-star-four-points-outline',
'page.upload.file': 'mdi-file-upload-outline',
'attribute.upload.file': 'mdi-file-upload-outline',
'button.filter': 'mdi-filter',
'attribute.filter': 'mdi-filter',
'button.menu.search': 'mdi-filter-menu-outline',
'page.filter.none': 'mdi-filter-off-outline',
'page.filter.list': 'mdi-filter-outline',
'attribute.account.country': 'mdi-flag-outline',
'attribute.cdn.country': 'mdi-flag-outline',
'error.message': 'mdi-flash-triangle-outline',
'card.tex-archive': 'mdi-folder-multiple-outline',
'page.tex-archive': 'mdi-folder-multiple-outline',
'file.type.d.open': 'mdi-folder-open-outline',
'file.type.directory.open': 'mdi-folder-open-outline',
'file.type.d': 'mdi-folder-outline',
'attribute.upload.path': 'mdi-folder-outline',
'file.type.directory': 'mdi-folder-outline',
'attribute.tex-archive-notes.path': 'mdi-folder-outline',
'attribute.tex-archive-notes.text.de': 'mdi-folder-text',
'attribute.tex-archive-notes.text.en': 'mdi-folder-text-outline',
'page.changelog': 'mdi-format-list-text',
'page.changelog.item': 'mdi-format-list-bulleted-square',
'attribute.license.text': 'mdi-format-section',
'entity.license': 'mdi-gavel',
'page.licenses': 'mdi-gavel',
'card.licenses': 'mdi-gavel',
'entity.pkg.obsolete': 'mdi-hand-front-right-outline',
'pkg.orphaned': 'mdi-hand-pointing-up',
'item.team.role': 'mdi-hard-hat',
'tip.title': 'mdi-head-question',
'page.help': 'mdi-help-box-multiple-outline',
'attribute.pkg.support': 'mdi-help-circle-outline',
'attribute.upload.support': 'mdi-help-circle-outline',
'card.wanted': 'mdi-hand-front-right-outline',
'page.cover': 'mdi-home',
'page.user.home': 'mdi-home-account',
'attribute.pkg.home': 'mdi-home-outline',
'attribute.upload.home': 'mdi-home-outline',
'gender.f': 'mdi-human-female',
'gender.m': 'mdi-human-male',
'gender.g': 'mdi-human-queue',
'attribute.license.key': 'mdi-identifier',
'file.readme': 'mdi-information',
'file.name.readme': 'mdi-information',
'file.name.README': 'mdi-information',
'file.name.Readme': 'mdi-information',
'card.tex': 'mdi-information-outline',
'info.i': 'mdi-information-outline',
'file.name.README.md': 'mdi-information-outline',
'page.about': 'mdi-information-outline',
'search.message.I': 'mdi-information-outline',
'tab.readme': 'mdi-information-outline',
'attribute.account.passwd.1': 'mdi-key-variant',
'attribute.account.passwd.2': 'mdi-key-variant',
'page.admin.catalogue': 'mdi-library-shelves',
'file.ext.bib': 'mdi-library-shelves',
'file.name.COPYING': 'mdi-license',
'file.name.LICENSE': 'mdi-license',
'button.search.help': 'mdi-lifebuoy',
'page.help.faq': 'mdi-lightbulb-question-outline',
'search.message.E': 'mdi-lightning-bolt-circle',
'attribute.license.url': 'mdi-link',
'button.link': 'mdi-link-variant',
'button.login': 'mdi-login-variant',
'button.logout': 'mdi-logout',
'page.search': 'mdi-magnify',
'button.search': 'mdi-magnify',
'button.search.close': 'mdi-magnify-minus-outline',
'button.search.open': 'mdi-magnify-plus-outline',
'button.search.reset': 'mdi-magnify-remove-outline',
'attribute.lug.address': 'mdi-mail',
'tab.my.visited': 'mdi-map-marker-multiple-outline',
'page.visited': 'mdi-map-marker-multiple-outline',
'tab.visited': 'mdi-map-marker-multiple-outline',
'indicator.visited': 'mdi-map-marker-outline',
'page.sitemap': 'mdi-map-outline',
'button.menu.left': 'mdi-menu-left-outline',
'button.menu.right': 'mdi-menu-right-outline',
'button.menu.down': 'mdi-menu-down',
'page.admin.message': 'mdi-message-fast-outline',
'page.admin.messages': 'mdi-message-outline',
'attribute.upload.announcement': 'mdi-message-outline',
'attribute.feedback.concern': 'mdi-message-question',
'attribute.feedback.reply': 'mdi-message-reply-text-outline',
'attribute.message.title': 'mdi-message-text',
'card.message': 'mdi-message-text-fast-outline',
'attribute.message.text': 'mdi-message-text-outline',
'card.cdn': 'mdi-mirror',
'page.cdn': 'mdi-mirror',
'page.cdn.list': 'mdi-mirror',
'page.cdn.become': 'mdi-mirror-variant',
'markdown.tab.preview': 'mdi-monitor',
'theme.dark': 'mdi-moon-waning-crescent',
'pkg.new': 'mdi-new-box',
'page.ctan-ann': 'mdi-newspaper-variant-multiple-outline',
'entity.announcement': 'mdi-newspaper-variant-outline',
'attribute.ctan-ann.summary': 'mdi-newspaper-variant-outline',
'attribute.lug.periodical': 'mdi-newspaper-variant-outline',
'attribute.pkg.announce': 'mdi-newspaper-variant-outline',
'attribute.upload.announce': 'mdi-newspaper-variant-outline',
'page.announcement': 'mdi-newspaper-variant-outline',
'attribute.pkg.version': 'mdi-numeric',
'attribute.upload.version': 'mdi-numeric',
'section.packages': 'mdi-package',
'entity.pkg.open': 'mdi-package-variant',
'entity.pkg': 'mdi-package-variant-closed',
'card.package': 'mdi-package-variant-closed',
'tab.package': 'mdi-package-variant-closed',
'tab.pkg': 'mdi-package-variant-closed',
'pkg.exists': 'mdi-package-variant-closed-check',
'tab.install.pkg': 'mdi-package-variant-closed-plus',
'section.contributions': 'mdi-package-variant-closed-plus',
'button.ctrl.pause': 'mdi-pause',
'attribute.cdn.notes': 'mdi-pen',
'field.edit': 'mdi-pen',
'section.my.settings': 'mdi-pen',
'field.create': 'mdi-pen-plus',
'field.edit.default': 'mdi-pencil-circle-outline',
'page.markdown': 'mdi-pencil-ruler-outline',
'page.help.markdown': 'mdi-pencil-ruler-outline',
'button.ctrl.play': 'mdi.play',
'button.create': 'mdi-plus-circle-outline',
'button.cdn.submit': 'mdi-plus-circle-outline',
'page.cdn.register': 'mdi-plus-network-outline',
'attribute.message.type': 'mdi-pound',
'dialog.login': 'mdi-power',
'account.enabled.false': 'mdi-progress-question',
'page.incoming': 'mdi-progress-upload',
'page.upload.incoming': 'mdi-progress-upload',
'attribute.cdn.ftp': 'mdi-protocol',
'attribute.cdn.http': 'mdi-protocol',
'attribute.cdn.https': 'mdi-protocol',
'attribute.cdn.rsync': 'mdi-protocol',
'attribute.upload.type': 'mdi-radar',
'button.reset': 'mdi-restore',
'page.admin.run': 'mdi-run',
'page.admin.logs.apache': 'mdi-script-text',
'page.admin.logs.server': 'mdi-script-text',
'page.admin.logs.update': 'mdi-script-text',
'button.search.history': 'mdi-select-search',
'attribute.cdn.name': 'mdi-server',
'attribute.upload.server': 'mdi-server-network',
'page.privacy': 'mdi-shield-check',
'card.password': 'mdi-shield-key-outline',
'dialog.password': 'mdi-shield-key-outline',
'account.locked.true': 'mdi-shield-lock-outline',
'account.locked.false': 'mdi-shield-lock-open-outline',
'attribute.account.password': 'mdi-shield-lock-open-outline',
'dialog.passwd': 'mdi-shield-refresh-outline',
'attribute.lug.languages': 'mdi-sign-language',
'button.ctrl.next': 'mdi-skip-next',
'button.ctrl.previous': 'mdi-skip-previous',
'star.full': 'mdi-star',
'label.my.rating': 'mdi-star-box-multiple-outline',
'tab.pkg.ratings': 'mdi-star-box-multiple-outline',
'tab.my.ratings': 'mdi-star-box-multiple-outline',
'star.half': 'mdi-star-half',
'star.empty': 'mdi-star-outline',
'attribute.upload.status': 'mdi-state-machine',
'list.end': 'mdi-stop',
'entity.tex-archive-notes': 'mdi-subtitles-outline',
'page.credits': 'mdi-subtitles-outline',
'attribute.pkg.topics': 'mdi-tag-multiple-outline',
'attribute.upload.topics': 'mdi-tag-multiple-outline',
'card.topics': 'mdi-tag-multiple-outline',
'page.topics': 'mdi-tag-multiple-outline',
'entity.topic': 'mdi-tag-outline',
'attribute.license.details': 'mdi-text',
'attribute.account.description': 'mdi-text-account',
'page.help.markdown': 'mdi-text-box',
'tab.markdown': 'mdi-text-box',
'page.admin.logs': 'mdi-text-box-multiple-outline',
'attribute.license.name': 'mdi-text-box-outline',
'page.admin.search': 'mdi-text-search',
'button.no': 'mdi-thumb-down-outline',
'license.type.free': 'mdi-thumb-up-outline',
'button.yes': 'mdi-thumb-up-outline',
'info.passwd.ok': 'mdi-thumb-up-outline',
'dialog.confirm': 'mdi-thumbs-up-down-outline',
'page.admin.tickets': 'mdi-ticket-confirmation-outline',
'attribute.ticket.key': 'mdi-ticket-outline',
'tab.install': 'mdi-tools',
'attribute.pkg.development': 'mdi-tools',
'attribute.upload.development': 'mdi-tools',
'button.help.on': 'mdi-tooltip-question',
'button.help.off': 'mdi-tooltip-question-outline',
'button.upload': 'mdi-upload',
'card.upload': 'mdi-upload',
'page.upload': 'mdi-upload',
'page.admin.uploads': 'mdi-upload-multiple',
'button.upload.new': 'mdi-upload-outline',
'button.view.list': 'mdi-view-list',
'button.view-cards': 'mdi-view-module',
'entity.rating': 'mdi-vote-outline',
'theme.light': 'mdi-weather-sunny',
'attribute.lug.site': 'mdi-web',
'page.api.xml': 'mdi-xml',
'page.help.lion': 'mdi-zodiac-leo'
}
/**
* This is the plug-in for accessing the icons with logical names.
*
* @author Gerd Neugebauer <gene@ctan.org>
*/
export default defineNuxtPlugin(nuxtApp => {
/**
* Map the logical icon name to the mdi name.
* If the name starts with mdi_ then the argument is returned unchanged.
*/
nuxtApp.provide('icon', (name) => {
return name.startsWith('mdi-') ? name : ICON[name]
})
/**
* Provide access to the file type information.
*/
nuxtApp.provide('filetype', {
/**
* Provide access to the icon information.
*/
icon: (name, type) => {
if (type === 'f') {
const ext = name.replaceAll(/.*\./g, '.')
let icon = ICON[`file.ext${ext}`]
if (icon !== undefined) {
return icon
}
icon = ICON[`file.name.${name}`]
if (icon !== undefined) {
return icon
}
}
return ICON[`file.type.${type}`]
},
/**
*
*/
size: (bytes) => {
if (bytes > 1000000) {
return `${Math.floor(bytes / 1000000)}MB`
}
if (bytes > 1000) {
return `${Math.floor(bytes / 1000)}kB`
}
return `${bytes}B`
}
})
})