mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
Merge 89e8184ce7
into e1b4f9aafe
This commit is contained in:
commit
667835250c
7 changed files with 508 additions and 196 deletions
386
components.d.ts
vendored
386
components.d.ts
vendored
|
@ -1,193 +1,193 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
// Generated by unplugin-vue-components
|
// Generated by unplugin-vue-components
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
import '@vue/runtime-core'
|
import '@vue/runtime-core'
|
||||||
|
|
||||||
export {}
|
export {}
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
'404.page': typeof import('./src/pages/404.page.vue')['default']
|
'404.page': typeof import('./src/pages/404.page.vue')['default']
|
||||||
About: typeof import('./src/pages/About.vue')['default']
|
About: typeof import('./src/pages/About.vue')['default']
|
||||||
App: typeof import('./src/App.vue')['default']
|
App: typeof import('./src/App.vue')['default']
|
||||||
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
|
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
|
||||||
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
||||||
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
||||||
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
||||||
BasicAuthGenerator: typeof import('./src/tools/basic-auth-generator/basic-auth-generator.vue')['default']
|
BasicAuthGenerator: typeof import('./src/tools/basic-auth-generator/basic-auth-generator.vue')['default']
|
||||||
Bcrypt: typeof import('./src/tools/bcrypt/bcrypt.vue')['default']
|
Bcrypt: typeof import('./src/tools/bcrypt/bcrypt.vue')['default']
|
||||||
BenchmarkBuilder: typeof import('./src/tools/benchmark-builder/benchmark-builder.vue')['default']
|
BenchmarkBuilder: typeof import('./src/tools/benchmark-builder/benchmark-builder.vue')['default']
|
||||||
Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default']
|
Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default']
|
||||||
CAlert: typeof import('./src/ui/c-alert/c-alert.vue')['default']
|
CAlert: typeof import('./src/ui/c-alert/c-alert.vue')['default']
|
||||||
'CAlert.demo': typeof import('./src/ui/c-alert/c-alert.demo.vue')['default']
|
'CAlert.demo': typeof import('./src/ui/c-alert/c-alert.demo.vue')['default']
|
||||||
CameraRecorder: typeof import('./src/tools/camera-recorder/camera-recorder.vue')['default']
|
CameraRecorder: typeof import('./src/tools/camera-recorder/camera-recorder.vue')['default']
|
||||||
CaseConverter: typeof import('./src/tools/case-converter/case-converter.vue')['default']
|
CaseConverter: typeof import('./src/tools/case-converter/case-converter.vue')['default']
|
||||||
CButton: typeof import('./src/ui/c-button/c-button.vue')['default']
|
CButton: typeof import('./src/ui/c-button/c-button.vue')['default']
|
||||||
'CButton.demo': typeof import('./src/ui/c-button/c-button.demo.vue')['default']
|
'CButton.demo': typeof import('./src/ui/c-button/c-button.demo.vue')['default']
|
||||||
CButtonsSelect: typeof import('./src/ui/c-buttons-select/c-buttons-select.vue')['default']
|
CButtonsSelect: typeof import('./src/ui/c-buttons-select/c-buttons-select.vue')['default']
|
||||||
'CButtonsSelect.demo': typeof import('./src/ui/c-buttons-select/c-buttons-select.demo.vue')['default']
|
'CButtonsSelect.demo': typeof import('./src/ui/c-buttons-select/c-buttons-select.demo.vue')['default']
|
||||||
CCard: typeof import('./src/ui/c-card/c-card.vue')['default']
|
CCard: typeof import('./src/ui/c-card/c-card.vue')['default']
|
||||||
'CCard.demo': typeof import('./src/ui/c-card/c-card.demo.vue')['default']
|
'CCard.demo': typeof import('./src/ui/c-card/c-card.demo.vue')['default']
|
||||||
CCollapse: typeof import('./src/ui/c-collapse/c-collapse.vue')['default']
|
CCollapse: typeof import('./src/ui/c-collapse/c-collapse.vue')['default']
|
||||||
'CCollapse.demo': typeof import('./src/ui/c-collapse/c-collapse.demo.vue')['default']
|
'CCollapse.demo': typeof import('./src/ui/c-collapse/c-collapse.demo.vue')['default']
|
||||||
CDiffEditor: typeof import('./src/ui/c-diff-editor/c-diff-editor.vue')['default']
|
CDiffEditor: typeof import('./src/ui/c-diff-editor/c-diff-editor.vue')['default']
|
||||||
CFileUpload: typeof import('./src/ui/c-file-upload/c-file-upload.vue')['default']
|
CFileUpload: typeof import('./src/ui/c-file-upload/c-file-upload.vue')['default']
|
||||||
'CFileUpload.demo': typeof import('./src/ui/c-file-upload/c-file-upload.demo.vue')['default']
|
'CFileUpload.demo': typeof import('./src/ui/c-file-upload/c-file-upload.demo.vue')['default']
|
||||||
ChmodCalculator: typeof import('./src/tools/chmod-calculator/chmod-calculator.vue')['default']
|
ChmodCalculator: typeof import('./src/tools/chmod-calculator/chmod-calculator.vue')['default']
|
||||||
Chronometer: typeof import('./src/tools/chronometer/chronometer.vue')['default']
|
Chronometer: typeof import('./src/tools/chronometer/chronometer.vue')['default']
|
||||||
CInputText: typeof import('./src/ui/c-input-text/c-input-text.vue')['default']
|
CInputText: typeof import('./src/ui/c-input-text/c-input-text.vue')['default']
|
||||||
'CInputText.demo': typeof import('./src/ui/c-input-text/c-input-text.demo.vue')['default']
|
'CInputText.demo': typeof import('./src/ui/c-input-text/c-input-text.demo.vue')['default']
|
||||||
CKeyValueList: typeof import('./src/ui/c-key-value-list/c-key-value-list.vue')['default']
|
CKeyValueList: typeof import('./src/ui/c-key-value-list/c-key-value-list.vue')['default']
|
||||||
CKeyValueListItem: typeof import('./src/ui/c-key-value-list/c-key-value-list-item.vue')['default']
|
CKeyValueListItem: typeof import('./src/ui/c-key-value-list/c-key-value-list-item.vue')['default']
|
||||||
CLabel: typeof import('./src/ui/c-label/c-label.vue')['default']
|
CLabel: typeof import('./src/ui/c-label/c-label.vue')['default']
|
||||||
CLink: typeof import('./src/ui/c-link/c-link.vue')['default']
|
CLink: typeof import('./src/ui/c-link/c-link.vue')['default']
|
||||||
'CLink.demo': typeof import('./src/ui/c-link/c-link.demo.vue')['default']
|
'CLink.demo': typeof import('./src/ui/c-link/c-link.demo.vue')['default']
|
||||||
CMarkdown: typeof import('./src/ui/c-markdown/c-markdown.vue')['default']
|
CMarkdown: typeof import('./src/ui/c-markdown/c-markdown.vue')['default']
|
||||||
'CMarkdown.demo': typeof import('./src/ui/c-markdown/c-markdown.demo.vue')['default']
|
'CMarkdown.demo': typeof import('./src/ui/c-markdown/c-markdown.demo.vue')['default']
|
||||||
CModal: typeof import('./src/ui/c-modal/c-modal.vue')['default']
|
CModal: typeof import('./src/ui/c-modal/c-modal.vue')['default']
|
||||||
'CModal.demo': typeof import('./src/ui/c-modal/c-modal.demo.vue')['default']
|
'CModal.demo': typeof import('./src/ui/c-modal/c-modal.demo.vue')['default']
|
||||||
CModalValue: typeof import('./src/ui/c-modal-value/c-modal-value.vue')['default']
|
CModalValue: typeof import('./src/ui/c-modal-value/c-modal-value.vue')['default']
|
||||||
'CModalValue.demo': typeof import('./src/ui/c-modal-value/c-modal-value.demo.vue')['default']
|
'CModalValue.demo': typeof import('./src/ui/c-modal-value/c-modal-value.demo.vue')['default']
|
||||||
CollapsibleToolMenu: typeof import('./src/components/CollapsibleToolMenu.vue')['default']
|
CollapsibleToolMenu: typeof import('./src/components/CollapsibleToolMenu.vue')['default']
|
||||||
ColorConverter: typeof import('./src/tools/color-converter/color-converter.vue')['default']
|
ColorConverter: typeof import('./src/tools/color-converter/color-converter.vue')['default']
|
||||||
ColoredCard: typeof import('./src/components/ColoredCard.vue')['default']
|
ColoredCard: typeof import('./src/components/ColoredCard.vue')['default']
|
||||||
CommandPalette: typeof import('./src/modules/command-palette/command-palette.vue')['default']
|
CommandPalette: typeof import('./src/modules/command-palette/command-palette.vue')['default']
|
||||||
CommandPaletteOption: typeof import('./src/modules/command-palette/components/command-palette-option.vue')['default']
|
CommandPaletteOption: typeof import('./src/modules/command-palette/components/command-palette-option.vue')['default']
|
||||||
CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default']
|
CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default']
|
||||||
CSelect: typeof import('./src/ui/c-select/c-select.vue')['default']
|
CSelect: typeof import('./src/ui/c-select/c-select.vue')['default']
|
||||||
'CSelect.demo': typeof import('./src/ui/c-select/c-select.demo.vue')['default']
|
'CSelect.demo': typeof import('./src/ui/c-select/c-select.demo.vue')['default']
|
||||||
CTable: typeof import('./src/ui/c-table/c-table.vue')['default']
|
CTable: typeof import('./src/ui/c-table/c-table.vue')['default']
|
||||||
'CTable.demo': typeof import('./src/ui/c-table/c-table.demo.vue')['default']
|
'CTable.demo': typeof import('./src/ui/c-table/c-table.demo.vue')['default']
|
||||||
CTextCopyable: typeof import('./src/ui/c-text-copyable/c-text-copyable.vue')['default']
|
CTextCopyable: typeof import('./src/ui/c-text-copyable/c-text-copyable.vue')['default']
|
||||||
'CTextCopyable.demo': typeof import('./src/ui/c-text-copyable/c-text-copyable.demo.vue')['default']
|
'CTextCopyable.demo': typeof import('./src/ui/c-text-copyable/c-text-copyable.demo.vue')['default']
|
||||||
CTooltip: typeof import('./src/ui/c-tooltip/c-tooltip.vue')['default']
|
CTooltip: typeof import('./src/ui/c-tooltip/c-tooltip.vue')['default']
|
||||||
'CTooltip.demo': typeof import('./src/ui/c-tooltip/c-tooltip.demo.vue')['default']
|
'CTooltip.demo': typeof import('./src/ui/c-tooltip/c-tooltip.demo.vue')['default']
|
||||||
DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default']
|
DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default']
|
||||||
'DemoHome.page': typeof import('./src/ui/demo/demo-home.page.vue')['default']
|
'DemoHome.page': typeof import('./src/ui/demo/demo-home.page.vue')['default']
|
||||||
DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default']
|
DemoWrapper: typeof import('./src/ui/demo/demo-wrapper.vue')['default']
|
||||||
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
|
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
|
||||||
DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default']
|
DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default']
|
||||||
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
|
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
|
||||||
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
||||||
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
||||||
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
|
EmojiCard: typeof import('./src/tools/emoji-picker/emoji-card.vue')['default']
|
||||||
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
|
EmojiGrid: typeof import('./src/tools/emoji-picker/emoji-grid.vue')['default']
|
||||||
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
|
EmojiPicker: typeof import('./src/tools/emoji-picker/emoji-picker.vue')['default']
|
||||||
Encryption: typeof import('./src/tools/encryption/encryption.vue')['default']
|
Encryption: typeof import('./src/tools/encryption/encryption.vue')['default']
|
||||||
EtaCalculator: typeof import('./src/tools/eta-calculator/eta-calculator.vue')['default']
|
EtaCalculator: typeof import('./src/tools/eta-calculator/eta-calculator.vue')['default']
|
||||||
FavoriteButton: typeof import('./src/components/FavoriteButton.vue')['default']
|
FavoriteButton: typeof import('./src/components/FavoriteButton.vue')['default']
|
||||||
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
|
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
|
||||||
GitMemo: typeof import('./src/tools/git-memo/git-memo.vue')['default']
|
GitMemo: typeof import('./src/tools/git-memo/git-memo.vue')['default']
|
||||||
'GitMemo.content': typeof import('./src/tools/git-memo/git-memo.content.md')['default']
|
'GitMemo.content': typeof import('./src/tools/git-memo/git-memo.content.md')['default']
|
||||||
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
|
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
|
||||||
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
|
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
|
||||||
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
|
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
|
||||||
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
|
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
|
||||||
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
|
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
|
||||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||||
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
|
||||||
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
|
||||||
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
|
||||||
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
|
||||||
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
|
||||||
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
||||||
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
||||||
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
||||||
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
||||||
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
IconMdiHeart: typeof import('~icons/mdi/heart')['default']
|
||||||
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
IconMdiSearch: typeof import('~icons/mdi/search')['default']
|
||||||
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
|
||||||
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
|
||||||
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
||||||
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
||||||
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
||||||
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
|
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
|
||||||
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
|
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
|
||||||
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
|
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
|
||||||
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
|
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
|
||||||
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
|
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
|
||||||
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
|
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
|
||||||
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
|
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
|
||||||
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
|
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
|
||||||
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
|
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
|
||||||
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
|
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
|
||||||
KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default']
|
KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default']
|
||||||
ListConverter: typeof import('./src/tools/list-converter/list-converter.vue')['default']
|
ListConverter: typeof import('./src/tools/list-converter/list-converter.vue')['default']
|
||||||
LocaleSelector: typeof import('./src/modules/i18n/components/locale-selector.vue')['default']
|
LocaleSelector: typeof import('./src/modules/i18n/components/locale-selector.vue')['default']
|
||||||
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
|
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
|
||||||
MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default']
|
MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default']
|
||||||
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
|
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
|
||||||
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
|
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
|
||||||
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
|
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
|
||||||
MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default']
|
MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default']
|
||||||
MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default']
|
MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default']
|
||||||
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
|
||||||
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
|
||||||
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
|
||||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||||
NCode: typeof import('naive-ui')['NCode']
|
NCode: typeof import('naive-ui')['NCode']
|
||||||
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
|
||||||
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
|
||||||
NDivider: typeof import('naive-ui')['NDivider']
|
NDivider: typeof import('naive-ui')['NDivider']
|
||||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||||
NGi: typeof import('naive-ui')['NGi']
|
NGi: typeof import('naive-ui')['NGi']
|
||||||
NGrid: typeof import('naive-ui')['NGrid']
|
NGrid: typeof import('naive-ui')['NGrid']
|
||||||
NH1: typeof import('naive-ui')['NH1']
|
NH1: typeof import('naive-ui')['NH1']
|
||||||
NH3: typeof import('naive-ui')['NH3']
|
NH3: typeof import('naive-ui')['NH3']
|
||||||
NIcon: typeof import('naive-ui')['NIcon']
|
NIcon: typeof import('naive-ui')['NIcon']
|
||||||
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
NInputNumber: typeof import('naive-ui')['NInputNumber']
|
||||||
NLabel: typeof import('naive-ui')['NLabel']
|
NLabel: typeof import('naive-ui')['NLabel']
|
||||||
NLayout: typeof import('naive-ui')['NLayout']
|
NLayout: typeof import('naive-ui')['NLayout']
|
||||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||||
NMenu: typeof import('naive-ui')['NMenu']
|
NMenu: typeof import('naive-ui')['NMenu']
|
||||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||||
NSpin: typeof import('naive-ui')['NSpin']
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
|
||||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||||
PdfSignatureChecker: typeof import('./src/tools/pdf-signature-checker/pdf-signature-checker.vue')['default']
|
PdfSignatureChecker: typeof import('./src/tools/pdf-signature-checker/pdf-signature-checker.vue')['default']
|
||||||
PdfSignatureDetails: typeof import('./src/tools/pdf-signature-checker/components/pdf-signature-details.vue')['default']
|
PdfSignatureDetails: typeof import('./src/tools/pdf-signature-checker/components/pdf-signature-details.vue')['default']
|
||||||
PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default']
|
PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default']
|
||||||
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
|
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
|
||||||
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
|
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
|
||||||
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
|
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
|
||||||
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
|
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
|
||||||
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
|
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
|
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
|
||||||
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
|
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
|
||||||
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
|
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
|
||||||
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
|
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
|
||||||
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
|
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
|
||||||
StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default']
|
StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default']
|
||||||
SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default']
|
SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default']
|
||||||
TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default']
|
TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default']
|
||||||
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
|
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
|
||||||
TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default']
|
TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default']
|
||||||
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
|
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
|
||||||
TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']
|
TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']
|
||||||
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
|
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
|
||||||
TextToUnicode: typeof import('./src/tools/text-to-unicode/text-to-unicode.vue')['default']
|
TextToUnicode: typeof import('./src/tools/text-to-unicode/text-to-unicode.vue')['default']
|
||||||
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
|
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
|
||||||
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
|
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
|
||||||
TomlToJson: typeof import('./src/tools/toml-to-json/toml-to-json.vue')['default']
|
TomlToJson: typeof import('./src/tools/toml-to-json/toml-to-json.vue')['default']
|
||||||
TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default']
|
TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default']
|
||||||
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
|
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
|
||||||
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
|
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
|
||||||
UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default']
|
UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default']
|
||||||
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
|
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
|
||||||
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
|
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
|
||||||
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']
|
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']
|
||||||
UserAgentResultCards: typeof import('./src/tools/user-agent-parser/user-agent-result-cards.vue')['default']
|
UserAgentResultCards: typeof import('./src/tools/user-agent-parser/user-agent-result-cards.vue')['default']
|
||||||
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
|
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
|
||||||
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
|
WifiQrCodeGenerator: typeof import('./src/tools/wifi-qr-code-generator/wifi-qr-code-generator.vue')['default']
|
||||||
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
|
XmlFormatter: typeof import('./src/tools/xml-formatter/xml-formatter.vue')['default']
|
||||||
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
|
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
|
||||||
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
|
YamlToToml: typeof import('./src/tools/yaml-to-toml/yaml-to-toml.vue')['default']
|
||||||
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']
|
YamlViewer: typeof import('./src/tools/yaml-viewer/yaml-viewer.vue')['default']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { tool as base64FileConverter } from './base64-file-converter';
|
import { tool as base64FileConverter } from './base64-file-converter';
|
||||||
import { tool as base64StringConverter } from './base64-string-converter';
|
import { tool as base64StringConverter } from './base64-string-converter';
|
||||||
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
import { tool as basicAuthGenerator } from './basic-auth-generator';
|
||||||
|
import { tool as raidCalculator } from './raid-calculator';
|
||||||
|
|
||||||
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
import { tool as asciiTextDrawer } from './ascii-text-drawer';
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ export const toolsByCategory: ToolCategory[] = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Math',
|
name: 'Math',
|
||||||
components: [mathEvaluator, etaCalculator, percentageCalculator],
|
components: [mathEvaluator, etaCalculator, percentageCalculator, raidCalculator],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Measurement',
|
name: 'Measurement',
|
||||||
|
|
12
src/tools/raid-calculator/index.ts
Normal file
12
src/tools/raid-calculator/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Database } from '@vicons/tabler';
|
||||||
|
import { defineTool } from '../tool';
|
||||||
|
|
||||||
|
export const tool = defineTool({
|
||||||
|
name: 'RAID Calculator',
|
||||||
|
path: '/raid-calculator',
|
||||||
|
description: 'Calculate storage capacity, fault tolerance and space efficiency of an array based on the number of disks, size, and RAID type',
|
||||||
|
keywords: ['raid', 'calculator'],
|
||||||
|
component: () => import('./raid-calculator.vue'),
|
||||||
|
icon: Database,
|
||||||
|
createdAt: new Date('2024-07-27'),
|
||||||
|
});
|
15
src/tools/raid-calculator/raid-calculator.e2e.spec.ts
Normal file
15
src/tools/raid-calculator/raid-calculator.e2e.spec.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('Tool - RAID Calculator', () => {
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
await page.goto('/raid-calculator');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Has correct title', async ({ page }) => {
|
||||||
|
await expect(page).toHaveTitle('RAID Calculator - IT Tools');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('', async ({ page }) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
151
src/tools/raid-calculator/raid-calculator.service.ts
Normal file
151
src/tools/raid-calculator/raid-calculator.service.ts
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
export { raidCalculations };
|
||||||
|
|
||||||
|
interface RaidType {
|
||||||
|
about: string
|
||||||
|
requirements: string
|
||||||
|
validate(num: number, size: number, stripeSize: number): boolean
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number): number
|
||||||
|
efficiency(num: number, stripeSize: number): number
|
||||||
|
fault(num: number, size: number, unit: number): string
|
||||||
|
}
|
||||||
|
|
||||||
|
const raidCalculations: { [key: string]: RaidType } = {
|
||||||
|
raid_0: {
|
||||||
|
about: 'RAID 0 splits data evenly across 2 or more disks without redunancy or fault tolerance creating one large storage space.',
|
||||||
|
requirements: 'RAID 0 requires at least 1 disk',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num > 1;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// total disks * size
|
||||||
|
return (num * size) * unit;
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// uses 100% of space
|
||||||
|
return 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
return 'None';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_1: {
|
||||||
|
about: 'RAID 1 consists of an exact copy of the data (mirror) across two or more disks. The array will operate as long as at least one drive is operational.',
|
||||||
|
requirements: 'RAID 1 requires at least 1 disk',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num > 1;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// total size is size of a single drive
|
||||||
|
return size * unit;
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1/N
|
||||||
|
return (1 / num) * 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// FT = total - 1
|
||||||
|
return `${num - 1} drive failures`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_5: {
|
||||||
|
about: 'RAID 5 uses block level striping with parity. This allows for fault tolerance with a storage reduction equal to one drive for the parity information.',
|
||||||
|
requirements: 'RAID 5 requires at least 3 disks',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num >= 3;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// (N-1) * S (one drive for parity)
|
||||||
|
return ((num - 1) * size) * unit;
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1 - (1/N)
|
||||||
|
return (1 - (1 / num)) * 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// always 1 failure
|
||||||
|
return '1 drive failure';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_6: {
|
||||||
|
about: 'RAID 6 is similiar to RAID 5 but with an additional parity block. This allows for an additional disk failure at the cost of storage reduction equal to two drives.',
|
||||||
|
requirements: 'RAID 6 requires at least 4 disks',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num >= 4;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// (N-2) * S (2 parity)
|
||||||
|
return ((num - 2) * size) * unit;
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1 - (2/N)
|
||||||
|
return (1 - (2 / num)) * 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// always 2 drive failures
|
||||||
|
return '2 drive failures';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_10: {
|
||||||
|
about: 'RAID 10 is a stripe of mirrors (RAID 1 + RAID 0). Each set of drives is mirrored and striped together so that each drive in the set is fault tolerant within the group.',
|
||||||
|
requirements: 'RAID 10 requires an even number of at least 4 disks',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num >= 4 && num % 2 === 0;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// Total disks (stripe)/2 (mirror)
|
||||||
|
return ((num * size) / 2) * unit;
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1/2 (1/strips per stripe, 2 in this case)
|
||||||
|
return 50;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// one per mirror
|
||||||
|
return '1 drive failure per mirrored set';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_50: {
|
||||||
|
about: 'RAID 50 stripes multiple RAID 5 arrays together (RAID 5 + RAID 0). Each RAID 5 set can sustain a single drive failure.',
|
||||||
|
requirements: 'RAID 50 requires at least 6 disks with 3 minimum per stripe. Stripes must contain an equal number of disks.',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num >= 6 && stripeSize >= 3 && num % stripeSize === 0;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// RAID 5 per stripe
|
||||||
|
const perStripe = ((stripeSize - 1) * size) * unit;
|
||||||
|
|
||||||
|
// sum each stripe
|
||||||
|
return perStripe * (num / stripeSize);
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1 - (1 / strips per stripe)
|
||||||
|
return (1 - (1 / stripeSize)) * 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// one per set
|
||||||
|
return '1 drive failure per RAID 5 set';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raid_60: {
|
||||||
|
about: 'RAID 60 stripes multiple RAID 6 arrays together (RAID 6 + RAID 0). Each RAID 6 set can sustain a two drive failures.',
|
||||||
|
requirements: 'RAID 60 requires at least 8 disks with 4 minimum per stripe. Stripes must contain an equal number of disks.',
|
||||||
|
validate(num: number, size: number, stripeSize: number) {
|
||||||
|
return num >= 8 && stripeSize >= 4 && num % stripeSize === 0;
|
||||||
|
},
|
||||||
|
capacity(num: number, size: number, stripeSize: number, unit: number) {
|
||||||
|
// RAID 6 per stripe
|
||||||
|
const perStripe = ((stripeSize - 2) * size) * unit;
|
||||||
|
|
||||||
|
// sum each stripe
|
||||||
|
return perStripe * (num / stripeSize);
|
||||||
|
},
|
||||||
|
efficiency(num: number, stripeSize: number) {
|
||||||
|
// 1 - (2 / strips per stripe)
|
||||||
|
return (1 - (2 / stripeSize)) * 100;
|
||||||
|
},
|
||||||
|
fault(num: number, size: number, unit: number) {
|
||||||
|
// 2 per set
|
||||||
|
return '2 drive failures per RAID 6 set';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
128
src/tools/raid-calculator/raid-calculator.vue
Normal file
128
src/tools/raid-calculator/raid-calculator.vue
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { raidCalculations } from './raid-calculator.service';
|
||||||
|
import { UNIT_BASE, formatBytes } from '@/utils/convert';
|
||||||
|
|
||||||
|
const diskTotal = ref(2);
|
||||||
|
const diskSize = ref(100);
|
||||||
|
const diskUnit = ref(10 ** 9);
|
||||||
|
const diskPerStripe = ref(3);
|
||||||
|
const raidType = ref('raid_0');
|
||||||
|
const raidInfo = computed(() => raidCalculations[raidType.value].about);
|
||||||
|
const raidRequirements = computed(() => raidCalculations[raidType.value].requirements);
|
||||||
|
const inputsValid = computed(() => validateSetup());
|
||||||
|
|
||||||
|
const totalStripes = computed(() => {
|
||||||
|
if (inputsValid.value) {
|
||||||
|
return `${diskTotal.value / diskPerStripe.value} stripes total`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculatedCapacity = computed(() => {
|
||||||
|
return formatBytes(raidCalculations[raidType.value].capacity(diskTotal.value, diskSize.value, diskPerStripe.value, diskUnit.value), 2, UNIT_BASE.BASE_10);
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculatedFaultTolerance = computed(() => {
|
||||||
|
return raidCalculations[raidType.value].fault(diskTotal.value, diskSize.value, diskUnit.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const calculatedSpaceEfficiency = computed(() => {
|
||||||
|
return raidCalculations[raidType.value].efficiency(diskTotal.value, diskPerStripe.value).toFixed(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
function validateSetup() {
|
||||||
|
// validate the selected RAID type against parameters
|
||||||
|
return raidCalculations[raidType.value].validate(diskTotal.value, diskSize.value, diskPerStripe.value);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<c-card>
|
||||||
|
<n-form-item label="Number of disks" label-placement="left" label-width="150" mb-2>
|
||||||
|
<n-input-number v-model:value="diskTotal" max="10000" min="2" placeholder="Number of disks (ex: 2)" w-full />
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
<n-form-item label="Disk size" label-placement="left" label-width="150" mb-2>
|
||||||
|
<n-input-number v-model:value="diskSize" max="10000" min="1" placeholder="Disk size (ex: 100)" w-full />
|
||||||
|
<div flex items-baseline gap-2>
|
||||||
|
<c-select
|
||||||
|
v-model:value="diskUnit"
|
||||||
|
min-w-130px
|
||||||
|
ml-1
|
||||||
|
:options="[
|
||||||
|
{ label: 'MB', value: 10 ** 6 },
|
||||||
|
{ label: 'GB', value: 10 ** 9 },
|
||||||
|
{ label: 'TB', value: 10 ** 12 },
|
||||||
|
{ label: 'PB', value: 10 ** 15 },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item v-if="['raid_50', 'raid_60'].includes(raidType)" label="Disks per stripe" label-placement="left" label-width="150" mb-2>
|
||||||
|
<n-input-number v-model:value="diskPerStripe" max="10000" min="2" placeholder="Number of disks per stripe (ex: 3)" w-full />
|
||||||
|
<n-input v-model:value="totalStripes" placeholder="" ml-1 w-full readonly />
|
||||||
|
</n-form-item>
|
||||||
|
<n-form-item label="RAID Type" label-placement="left" label-width="150" mb-2>
|
||||||
|
<c-select
|
||||||
|
v-model:value="raidType"
|
||||||
|
w-full
|
||||||
|
:options="[
|
||||||
|
{ label: 'RAID 0 (stripe)', value: 'raid_0' },
|
||||||
|
{ label: 'RAID 1 (mirror)', value: 'raid_1' },
|
||||||
|
{ label: 'RAID 5 (parity)', value: 'raid_5' },
|
||||||
|
{ label: 'RAID 6 (double parity)', value: 'raid_6' },
|
||||||
|
{ label: 'RAID 10 (mirror + stripe)', value: 'raid_10' },
|
||||||
|
{ label: 'RAID 50 (parity + stripe)', value: 'raid_50' },
|
||||||
|
{ label: 'RAID 60 (double parity + stripe)', value: 'raid_60' },
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</n-form-item>
|
||||||
|
<p v-if="!inputsValid" class="raidError">
|
||||||
|
{{ raidRequirements }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ raidInfo }}<br /><br />
|
||||||
|
For more information on RAID types, see <a href="https://en.wikipedia.org/wiki/Standard_RAID_levels" target="_blank" rel="noopener">Wikipedia</a>.
|
||||||
|
</p>
|
||||||
|
</c-card>
|
||||||
|
<c-card title="Results">
|
||||||
|
<n-table v-if="inputsValid">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td font-bold width="30%">
|
||||||
|
Capacity
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ calculatedCapacity }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td font-bold width="30%">
|
||||||
|
Fault Tolerance
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ calculatedFaultTolerance }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td font-bold width="30%">
|
||||||
|
Space Efficiency
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ calculatedSpaceEfficiency }}%
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</n-table>
|
||||||
|
</c-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.raidError {
|
||||||
|
color: rgb(208, 48, 80)
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,9 +1,14 @@
|
||||||
export function formatBytes(bytes: number, decimals = 2) {
|
export enum UNIT_BASE {
|
||||||
|
BASE_2 = 1024,
|
||||||
|
BASE_10 = 1000,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatBytes(bytes: number, decimals = 2, base: UNIT_BASE = UNIT_BASE.BASE_2) {
|
||||||
if (bytes === 0) {
|
if (bytes === 0) {
|
||||||
return '0 Bytes';
|
return '0 Bytes';
|
||||||
}
|
}
|
||||||
|
|
||||||
const k = 1024;
|
const k = base;
|
||||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue