mirror of
https://github.com/CorentinTh/it-tools.git
synced 2024-09-11 13:37:53 +03:00
Compare commits
3 Commits
c0321de01e
...
ffd5a9d98c
Author | SHA1 | Date | |
---|---|---|---|
|
ffd5a9d98c | ||
|
2a4462ccaf | ||
|
a465baf86d |
2
components.d.ts
vendored
2
components.d.ts
vendored
@ -144,7 +144,9 @@ declare module '@vue/runtime-core' {
|
||||
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
|
||||
NMenu: typeof import('naive-ui')['NMenu']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
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']
|
||||
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
|
||||
|
@ -49,6 +49,7 @@
|
||||
"@vueuse/router": "^10.0.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"change-case": "^4.1.2",
|
||||
"chinesegen": "^0.3.3",
|
||||
"colord": "^2.9.3",
|
||||
"composerize-ts": "^0.6.2",
|
||||
"country-code-lookup": "^0.1.0",
|
||||
@ -69,6 +70,7 @@
|
||||
"jwt-decode": "^3.1.2",
|
||||
"libphonenumber-js": "^1.10.28",
|
||||
"lodash": "^4.17.21",
|
||||
"lorem-ipsum-japanese": "^1.0.1",
|
||||
"marked": "^10.0.0",
|
||||
"mathjs": "^11.9.1",
|
||||
"mime-types": "^2.1.35",
|
||||
@ -138,5 +140,6 @@
|
||||
"vitest": "^0.34.0",
|
||||
"workbox-window": "^7.0.0",
|
||||
"zx": "^7.2.1"
|
||||
}
|
||||
},
|
||||
"packageManager": "pnpm@8.15.3"
|
||||
}
|
||||
|
@ -47,6 +47,9 @@ dependencies:
|
||||
change-case:
|
||||
specifier: ^4.1.2
|
||||
version: 4.1.2
|
||||
chinesegen:
|
||||
specifier: ^0.3.3
|
||||
version: 0.3.3
|
||||
colord:
|
||||
specifier: ^2.9.3
|
||||
version: 2.9.3
|
||||
@ -107,6 +110,9 @@ dependencies:
|
||||
lodash:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
lorem-ipsum-japanese:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
marked:
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
@ -3354,7 +3360,7 @@ packages:
|
||||
dependencies:
|
||||
'@unhead/dom': 0.5.1
|
||||
'@unhead/schema': 0.5.1
|
||||
'@vueuse/shared': 10.8.0(vue@3.3.4)
|
||||
'@vueuse/shared': 10.11.0(vue@3.3.4)
|
||||
unhead: 0.5.1
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
@ -3987,19 +3993,19 @@ packages:
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@10.3.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
||||
/@vueuse/shared@10.11.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.5(vue@3.3.4)
|
||||
vue-demi: 0.14.8(vue@3.3.4)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/@vueuse/shared@10.8.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==}
|
||||
/@vueuse/shared@10.3.0(vue@3.3.4):
|
||||
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
||||
dependencies:
|
||||
vue-demi: 0.14.7(vue@3.3.4)
|
||||
vue-demi: 0.14.5(vue@3.3.4)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
@ -4447,6 +4453,13 @@ packages:
|
||||
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
||||
dev: true
|
||||
|
||||
/chinesegen@0.3.3:
|
||||
resolution: {integrity: sha512-iwWTX4sPT8BwYaZr3SFr4D1tkToc1SXQ90AwnW8prCcGhv2nrOW38LStV27HtbHPUYTEhYbfG1KHoXRtqVBUFg==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
dev: false
|
||||
|
||||
/chokidar@3.5.3:
|
||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
@ -6720,6 +6733,13 @@ packages:
|
||||
is-unicode-supported: 0.1.0
|
||||
dev: true
|
||||
|
||||
/lorem-ipsum-japanese@1.0.1:
|
||||
resolution: {integrity: sha512-lL4XsigcYfSIsuUmHuoLB4wa71teS7XCx5tDgyZh6SoQmtwn0NTTMM54F69hy5aT8dkExH41hKmmOh1cET6I/w==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
optimist: 0.3.7
|
||||
dev: false
|
||||
|
||||
/loupe@2.3.6:
|
||||
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
|
||||
dependencies:
|
||||
@ -6932,7 +6952,6 @@ packages:
|
||||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: true
|
||||
|
||||
/mlly@1.4.0:
|
||||
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
|
||||
@ -7179,6 +7198,12 @@ packages:
|
||||
is-wsl: 2.2.0
|
||||
dev: true
|
||||
|
||||
/optimist@0.3.7:
|
||||
resolution: {integrity: sha512-TCx0dXQzVtSCg2OgY/bO9hjM9cV4XYx09TVK+s3+FhkjT6LovsLe+pPMzpWf+6yXK/hUizs2gUoTw3jHM0VaTQ==}
|
||||
dependencies:
|
||||
wordwrap: 0.0.3
|
||||
dev: false
|
||||
|
||||
/optionator@0.9.3:
|
||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -9158,8 +9183,8 @@ packages:
|
||||
vue: 3.3.4
|
||||
dev: false
|
||||
|
||||
/vue-demi@0.14.7(vue@3.3.4):
|
||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||
/vue-demi@0.14.8(vue@3.3.4):
|
||||
resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
@ -9371,6 +9396,11 @@ packages:
|
||||
stackback: 0.0.2
|
||||
dev: true
|
||||
|
||||
/wordwrap@0.0.3:
|
||||
resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/workbox-background-sync@7.0.0:
|
||||
resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==}
|
||||
dependencies:
|
||||
@ -9449,6 +9479,7 @@ packages:
|
||||
|
||||
/workbox-google-analytics@7.0.0:
|
||||
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
||||
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
|
||||
dependencies:
|
||||
workbox-background-sync: 7.0.0
|
||||
workbox-core: 7.0.0
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { useRouteQuery } from '@vueuse/router';
|
||||
import { computed } from 'vue';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
|
||||
export { useQueryParam };
|
||||
export { useQueryParam, useQueryParamOrStorage };
|
||||
|
||||
const transformers = {
|
||||
number: {
|
||||
@ -16,6 +17,12 @@ const transformers = {
|
||||
fromQuery: (value: string) => value.toLowerCase() === 'true',
|
||||
toQuery: (value: boolean) => (value ? 'true' : 'false'),
|
||||
},
|
||||
object: {
|
||||
fromQuery: (value: string) => {
|
||||
return JSON.parse(value);
|
||||
},
|
||||
toQuery: (value: object) => JSON.stringify(value),
|
||||
},
|
||||
};
|
||||
|
||||
function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue: T }) {
|
||||
@ -33,3 +40,27 @@ function useQueryParam<T>({ name, defaultValue }: { name: string; defaultValue:
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function useQueryParamOrStorage<T>({ name, storageName, defaultValue }: { name: string; storageName: string; defaultValue: T }) {
|
||||
const type = typeof defaultValue;
|
||||
const transformer = transformers[type as keyof typeof transformers] ?? transformers.string;
|
||||
|
||||
const storageRef = useStorage(storageName, defaultValue);
|
||||
const proxyDefaultValue = transformer.toQuery(defaultValue as never);
|
||||
const proxy = useRouteQuery(name, proxyDefaultValue);
|
||||
|
||||
const r = ref(defaultValue);
|
||||
|
||||
watch(r,
|
||||
(value) => {
|
||||
proxy.value = transformer.toQuery(value as never);
|
||||
storageRef.value = value as never;
|
||||
},
|
||||
{ deep: true });
|
||||
|
||||
r.value = (proxy.value && proxy.value !== proxyDefaultValue
|
||||
? transformer.fromQuery(proxy.value) as unknown as T
|
||||
: storageRef.value as T) as never;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
7
src/tools/lorem-ipsum-generator/chinesegen.d.ts
vendored
Normal file
7
src/tools/lorem-ipsum-generator/chinesegen.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
declare module 'chinesegen' {
|
||||
export default function lorem(config: {
|
||||
count: number,
|
||||
}): {
|
||||
text: string
|
||||
};
|
||||
}
|
@ -1,185 +1,39 @@
|
||||
import _ from 'lodash';
|
||||
import loremIpsumJapanese from 'lorem-ipsum-japanese';
|
||||
import chinesegen from 'chinesegen';
|
||||
import languageLorems from './lorem-ipsum.i18n.json';
|
||||
import { randFromArray } from '@/utils/random';
|
||||
|
||||
const vocabulary = [
|
||||
'a',
|
||||
'ac',
|
||||
'accumsan',
|
||||
'ad',
|
||||
'adipiscing',
|
||||
'aenean',
|
||||
'aliquam',
|
||||
'aliquet',
|
||||
'amet',
|
||||
'ante',
|
||||
'aptent',
|
||||
'arcu',
|
||||
'at',
|
||||
'auctor',
|
||||
'bibendum',
|
||||
'blandit',
|
||||
'class',
|
||||
'commodo',
|
||||
'condimentum',
|
||||
'congue',
|
||||
'consectetur',
|
||||
'consequat',
|
||||
'conubia',
|
||||
'convallis',
|
||||
'cras',
|
||||
'cubilia',
|
||||
'cum',
|
||||
'curabitur',
|
||||
'curae',
|
||||
'dapibus',
|
||||
'diam',
|
||||
'dictum',
|
||||
'dictumst',
|
||||
'dignissim',
|
||||
'dolor',
|
||||
'donec',
|
||||
'dui',
|
||||
'duis',
|
||||
'egestas',
|
||||
'eget',
|
||||
'eleifend',
|
||||
'elementum',
|
||||
'elit',
|
||||
'enim',
|
||||
'erat',
|
||||
'eros',
|
||||
'est',
|
||||
'et',
|
||||
'etiam',
|
||||
'eu',
|
||||
'euismod',
|
||||
'facilisi',
|
||||
'faucibus',
|
||||
'felis',
|
||||
'fermentum',
|
||||
'feugiat',
|
||||
'fringilla',
|
||||
'fusce',
|
||||
'gravida',
|
||||
'habitant',
|
||||
'habitasse',
|
||||
'hac',
|
||||
'hendrerit',
|
||||
'himenaeos',
|
||||
'iaculis',
|
||||
'id',
|
||||
'imperdiet',
|
||||
'in',
|
||||
'inceptos',
|
||||
'integer',
|
||||
'interdum',
|
||||
'ipsum',
|
||||
'justo',
|
||||
'lacinia',
|
||||
'lacus',
|
||||
'laoreet',
|
||||
'lectus',
|
||||
'leo',
|
||||
'ligula',
|
||||
'litora',
|
||||
'lobortis',
|
||||
'lorem',
|
||||
'luctus',
|
||||
'maecenas',
|
||||
'magna',
|
||||
'magnis',
|
||||
'malesuada',
|
||||
'massa',
|
||||
'mattis',
|
||||
'mauris',
|
||||
'metus',
|
||||
'mi',
|
||||
'molestie',
|
||||
'mollis',
|
||||
'montes',
|
||||
'morbi',
|
||||
'mus',
|
||||
'nam',
|
||||
'nascetur',
|
||||
'natoque',
|
||||
'nec',
|
||||
'neque',
|
||||
'netus',
|
||||
'nisi',
|
||||
'nisl',
|
||||
'non',
|
||||
'nostra',
|
||||
'nulla',
|
||||
'nullam',
|
||||
'nunc',
|
||||
'odio',
|
||||
'orci',
|
||||
'ornare',
|
||||
'parturient',
|
||||
'pellentesque',
|
||||
'penatibus',
|
||||
'per',
|
||||
'pharetra',
|
||||
'phasellus',
|
||||
'placerat',
|
||||
'platea',
|
||||
'porta',
|
||||
'porttitor',
|
||||
'posuere',
|
||||
'potenti',
|
||||
'praesent',
|
||||
'pretium',
|
||||
'primis',
|
||||
'proin',
|
||||
'pulvinar',
|
||||
'purus',
|
||||
'quam',
|
||||
'quis',
|
||||
'quisque',
|
||||
'rhoncus',
|
||||
'ridiculus',
|
||||
'risus',
|
||||
'rutrum',
|
||||
'sagittis',
|
||||
'sapien',
|
||||
'scelerisque',
|
||||
'sed',
|
||||
'sem',
|
||||
'semper',
|
||||
'senectus',
|
||||
'sit',
|
||||
'sociis',
|
||||
'sociosqu',
|
||||
'sodales',
|
||||
'sollicitudin',
|
||||
'suscipit',
|
||||
'suspendisse',
|
||||
'taciti',
|
||||
'tellus',
|
||||
'tempor',
|
||||
'tempus',
|
||||
'tincidunt',
|
||||
'torquent',
|
||||
'tortor',
|
||||
'turpis',
|
||||
'ullamcorper',
|
||||
'ultrices',
|
||||
'ultricies',
|
||||
'urna',
|
||||
'varius',
|
||||
'vehicula',
|
||||
'vel',
|
||||
'velit',
|
||||
'venenatis',
|
||||
'vestibulum',
|
||||
'vitae',
|
||||
'vivamus',
|
||||
'viverra',
|
||||
'volutpat',
|
||||
'vulputate',
|
||||
];
|
||||
const firstSentence = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
|
||||
|
||||
function generateSentence(length: number) {
|
||||
export function getSupportedLanguages() {
|
||||
return _.union(
|
||||
_.flatten(_.chain(languageLorems).map(l => l.languages).value()),
|
||||
['Japanese', 'Chinese'])
|
||||
.sort();
|
||||
}
|
||||
|
||||
function generateSentence(language: string, length: number) {
|
||||
if (language === 'Japanese') {
|
||||
return loremIpsumJapanese({
|
||||
count: length,
|
||||
units: 'words',
|
||||
});
|
||||
}
|
||||
if (language === 'Chinese') {
|
||||
return chinesegen({ count: length }).text;
|
||||
}
|
||||
|
||||
if (language === 'Emoticon') {
|
||||
const loremIcons = _.find(languageLorems, ({ languages }) => languages.includes(language))?.loremIpsum || '';
|
||||
const iconsChars = [...loremIcons];
|
||||
return Array.from({ length })
|
||||
.map(() => randFromArray(iconsChars))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
const vocabulary = _.find(languageLorems, ({ languages }) => languages.includes(language))?.loremIpsum?.split(' ') || [];
|
||||
|
||||
const sentence = Array.from({ length })
|
||||
.map(() => randFromArray(vocabulary))
|
||||
.join(' ');
|
||||
@ -193,15 +47,17 @@ export function generateLoremIpsum({
|
||||
wordCount = 10,
|
||||
startWithLoremIpsum = true,
|
||||
asHTML = false,
|
||||
language = 'English',
|
||||
}: {
|
||||
paragraphCount?: number
|
||||
sentencePerParagraph?: number
|
||||
wordCount?: number
|
||||
startWithLoremIpsum?: boolean
|
||||
asHTML?: boolean
|
||||
language?: string
|
||||
}) {
|
||||
const paragraphs = Array.from({ length: paragraphCount }).map(() =>
|
||||
Array.from({ length: sentencePerParagraph }).map(() => generateSentence(wordCount)),
|
||||
Array.from({ length: sentencePerParagraph }).map(() => generateSentence(language, wordCount)),
|
||||
);
|
||||
|
||||
if (startWithLoremIpsum) {
|
||||
|
@ -1,14 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { generateLoremIpsum } from './lorem-ipsum-generator.service';
|
||||
import { generateLoremIpsum, getSupportedLanguages } from './lorem-ipsum-generator.service';
|
||||
import { useCopy } from '@/composable/copy';
|
||||
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||
import { randIntFromInterval } from '@/utils/random';
|
||||
|
||||
const paragraphs = ref(1);
|
||||
const sentences = ref([3, 8]);
|
||||
const words = ref([8, 15]);
|
||||
const paragraphs = useStorage('lorem:paragraphs', 1);
|
||||
const sentences = useStorage('lorem:sentences', [3, 8]);
|
||||
const words = useStorage('lorem:words', [8, 15]);
|
||||
const startWithLoremIpsum = ref(true);
|
||||
const asHTML = ref(false);
|
||||
const language = useQueryParamOrStorage({ defaultValue: 'English', storageName: 'lorem:lang', name: 'lang' });
|
||||
|
||||
const supportedLanguages = getSupportedLanguages();
|
||||
const loremIpsumText = computed(() =>
|
||||
generateLoremIpsum({
|
||||
paragraphCount: paragraphs.value,
|
||||
@ -16,6 +19,7 @@ const loremIpsumText = computed(() =>
|
||||
sentencePerParagraph: randIntFromInterval(sentences.value[0], sentences.value[1]),
|
||||
wordCount: randIntFromInterval(words.value[0], words.value[1]),
|
||||
startWithLoremIpsum: startWithLoremIpsum.value,
|
||||
language: language.value,
|
||||
}),
|
||||
);
|
||||
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
|
||||
@ -23,6 +27,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
|
||||
|
||||
<template>
|
||||
<c-card>
|
||||
<c-select
|
||||
v-model:value="language"
|
||||
searchable
|
||||
label="Language:"
|
||||
:options="Object.values(supportedLanguages)"
|
||||
mb-2
|
||||
/>
|
||||
<n-form-item label="Paragraphs" :show-feedback="false" label-width="200" label-placement="left">
|
||||
<n-slider v-model:value="paragraphs" :step="1" :min="1" :max="20" />
|
||||
</n-form-item>
|
||||
|
6
src/tools/lorem-ipsum-generator/lorem-ipsum-japanese.d.ts
vendored
Normal file
6
src/tools/lorem-ipsum-generator/lorem-ipsum-japanese.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
declare module 'lorem-ipsum-japanese' {
|
||||
export default function lorem(config: {
|
||||
count: number,
|
||||
units: 'words' | 'sentences' | 'paragraphs',
|
||||
}): string;
|
||||
}
|
208
src/tools/lorem-ipsum-generator/lorem-ipsum.i18n.json
Normal file
208
src/tools/lorem-ipsum-generator/lorem-ipsum.i18n.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user