mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 13:29:13 -04:00
Merge 40aad48cc0
into 76a19d218d
This commit is contained in:
commit
b0f6a386a3
9 changed files with 354 additions and 196 deletions
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']
|
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']
|
||||||
|
NSlider: typeof import('naive-ui')['NSlider']
|
||||||
NSpin: typeof import('naive-ui')['NSpin']
|
NSpin: typeof import('naive-ui')['NSpin']
|
||||||
|
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||||
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']
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"@vueuse/router": "^10.0.0",
|
"@vueuse/router": "^10.0.0",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"change-case": "^4.1.2",
|
"change-case": "^4.1.2",
|
||||||
|
"chinesegen": "^0.3.3",
|
||||||
"colord": "^2.9.3",
|
"colord": "^2.9.3",
|
||||||
"composerize-ts": "^0.6.2",
|
"composerize-ts": "^0.6.2",
|
||||||
"country-code-lookup": "^0.1.0",
|
"country-code-lookup": "^0.1.0",
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"libphonenumber-js": "^1.10.28",
|
"libphonenumber-js": "^1.10.28",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lorem-ipsum-japanese": "^1.0.1",
|
||||||
"marked": "^10.0.0",
|
"marked": "^10.0.0",
|
||||||
"mathjs": "^11.9.1",
|
"mathjs": "^11.9.1",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
|
|
51
pnpm-lock.yaml
generated
51
pnpm-lock.yaml
generated
|
@ -47,6 +47,9 @@ dependencies:
|
||||||
change-case:
|
change-case:
|
||||||
specifier: ^4.1.2
|
specifier: ^4.1.2
|
||||||
version: 4.1.2
|
version: 4.1.2
|
||||||
|
chinesegen:
|
||||||
|
specifier: ^0.3.3
|
||||||
|
version: 0.3.3
|
||||||
colord:
|
colord:
|
||||||
specifier: ^2.9.3
|
specifier: ^2.9.3
|
||||||
version: 2.9.3
|
version: 2.9.3
|
||||||
|
@ -107,6 +110,9 @@ dependencies:
|
||||||
lodash:
|
lodash:
|
||||||
specifier: ^4.17.21
|
specifier: ^4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
|
lorem-ipsum-japanese:
|
||||||
|
specifier: ^1.0.1
|
||||||
|
version: 1.0.1
|
||||||
marked:
|
marked:
|
||||||
specifier: ^10.0.0
|
specifier: ^10.0.0
|
||||||
version: 10.0.0
|
version: 10.0.0
|
||||||
|
@ -3354,7 +3360,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/dom': 0.5.1
|
'@unhead/dom': 0.5.1
|
||||||
'@unhead/schema': 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
|
unhead: 0.5.1
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -3987,19 +3993,19 @@ packages:
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared@10.3.0(vue@3.3.4):
|
/@vueuse/shared@10.11.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.14.5(vue@3.3.4)
|
vue-demi: 0.14.8(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@vueuse/shared@10.8.0(vue@3.3.4):
|
/@vueuse/shared@10.3.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-dUdy6zwHhULGxmr9YUg8e+EnB39gcM4Fe2oKBSrh3cOsV30JcMPtsyuspgFCUo5xxFNaeMf/W2yyKfST7Bg8oQ==}
|
resolution: {integrity: sha512-kGqCTEuFPMK4+fNWy6dUOiYmxGcUbtznMwBZLC1PubidF4VZY05B+Oht7Jh7/6x4VOWGpvu3R37WHi81cKpiqg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
vue-demi: 0.14.7(vue@3.3.4)
|
vue-demi: 0.14.5(vue@3.3.4)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
@ -4447,6 +4453,13 @@ packages:
|
||||||
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/chinesegen@0.3.3:
|
||||||
|
resolution: {integrity: sha512-iwWTX4sPT8BwYaZr3SFr4D1tkToc1SXQ90AwnW8prCcGhv2nrOW38LStV27HtbHPUYTEhYbfG1KHoXRtqVBUFg==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
minimist: 1.2.8
|
||||||
|
dev: false
|
||||||
|
|
||||||
/chokidar@3.5.3:
|
/chokidar@3.5.3:
|
||||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||||
engines: {node: '>= 8.10.0'}
|
engines: {node: '>= 8.10.0'}
|
||||||
|
@ -6720,6 +6733,13 @@ packages:
|
||||||
is-unicode-supported: 0.1.0
|
is-unicode-supported: 0.1.0
|
||||||
dev: true
|
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:
|
/loupe@2.3.6:
|
||||||
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
|
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6932,7 +6952,6 @@ packages:
|
||||||
|
|
||||||
/minimist@1.2.8:
|
/minimist@1.2.8:
|
||||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/mlly@1.4.0:
|
/mlly@1.4.0:
|
||||||
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
|
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
|
||||||
|
@ -7179,6 +7198,12 @@ packages:
|
||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
dev: true
|
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:
|
/optionator@0.9.3:
|
||||||
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
@ -9158,8 +9183,8 @@ packages:
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/vue-demi@0.14.7(vue@3.3.4):
|
/vue-demi@0.14.8(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
@ -9371,6 +9396,11 @@ packages:
|
||||||
stackback: 0.0.2
|
stackback: 0.0.2
|
||||||
dev: true
|
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:
|
/workbox-background-sync@7.0.0:
|
||||||
resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==}
|
resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -9449,6 +9479,7 @@ packages:
|
||||||
|
|
||||||
/workbox-google-analytics@7.0.0:
|
/workbox-google-analytics@7.0.0:
|
||||||
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
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:
|
dependencies:
|
||||||
workbox-background-sync: 7.0.0
|
workbox-background-sync: 7.0.0
|
||||||
workbox-core: 7.0.0
|
workbox-core: 7.0.0
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useRouteQuery } from '@vueuse/router';
|
import { useRouteQuery } from '@vueuse/router';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import { useStorage } from '@vueuse/core';
|
||||||
|
|
||||||
export { useQueryParam };
|
export { useQueryParam, useQueryParamOrStorage };
|
||||||
|
|
||||||
const transformers = {
|
const transformers = {
|
||||||
number: {
|
number: {
|
||||||
|
@ -16,6 +17,12 @@ const transformers = {
|
||||||
fromQuery: (value: string) => value.toLowerCase() === 'true',
|
fromQuery: (value: string) => value.toLowerCase() === 'true',
|
||||||
toQuery: (value: boolean) => (value ? 'true' : 'false'),
|
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 }) {
|
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';
|
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.';
|
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 })
|
const sentence = Array.from({ length })
|
||||||
.map(() => randFromArray(vocabulary))
|
.map(() => randFromArray(vocabulary))
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
@ -193,15 +47,17 @@ export function generateLoremIpsum({
|
||||||
wordCount = 10,
|
wordCount = 10,
|
||||||
startWithLoremIpsum = true,
|
startWithLoremIpsum = true,
|
||||||
asHTML = false,
|
asHTML = false,
|
||||||
|
language = 'English',
|
||||||
}: {
|
}: {
|
||||||
paragraphCount?: number
|
paragraphCount?: number
|
||||||
sentencePerParagraph?: number
|
sentencePerParagraph?: number
|
||||||
wordCount?: number
|
wordCount?: number
|
||||||
startWithLoremIpsum?: boolean
|
startWithLoremIpsum?: boolean
|
||||||
asHTML?: boolean
|
asHTML?: boolean
|
||||||
|
language?: string
|
||||||
}) {
|
}) {
|
||||||
const paragraphs = Array.from({ length: paragraphCount }).map(() =>
|
const paragraphs = Array.from({ length: paragraphCount }).map(() =>
|
||||||
Array.from({ length: sentencePerParagraph }).map(() => generateSentence(wordCount)),
|
Array.from({ length: sentencePerParagraph }).map(() => generateSentence(language, wordCount)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (startWithLoremIpsum) {
|
if (startWithLoremIpsum) {
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { generateLoremIpsum } from './lorem-ipsum-generator.service';
|
import { generateLoremIpsum, getSupportedLanguages } from './lorem-ipsum-generator.service';
|
||||||
|
import { computedRefreshable } from '@/composable/computedRefreshable';
|
||||||
import { useCopy } from '@/composable/copy';
|
import { useCopy } from '@/composable/copy';
|
||||||
|
import { useQueryParamOrStorage } from '@/composable/queryParams';
|
||||||
import { randIntFromInterval } from '@/utils/random';
|
import { randIntFromInterval } from '@/utils/random';
|
||||||
|
|
||||||
const paragraphs = ref(1);
|
const paragraphs = useStorage('lorem:paragraphs', 1);
|
||||||
const sentences = ref([3, 8]);
|
const sentences = useStorage('lorem:sentences', [3, 8]);
|
||||||
const words = ref([8, 15]);
|
const words = useStorage('lorem:words', [8, 15]);
|
||||||
const startWithLoremIpsum = ref(true);
|
const startWithLoremIpsum = ref(true);
|
||||||
const asHTML = ref(false);
|
const asHTML = ref(false);
|
||||||
|
const language = useQueryParamOrStorage({ defaultValue: 'English', storageName: 'lorem:lang', name: 'lang' });
|
||||||
|
|
||||||
const loremIpsumText = computed(() =>
|
const supportedLanguages = getSupportedLanguages();
|
||||||
|
const [loremIpsumText, refreshLoremIpsum] = computedRefreshable(() =>
|
||||||
generateLoremIpsum({
|
generateLoremIpsum({
|
||||||
paragraphCount: paragraphs.value,
|
paragraphCount: paragraphs.value,
|
||||||
asHTML: asHTML.value,
|
asHTML: asHTML.value,
|
||||||
sentencePerParagraph: randIntFromInterval(sentences.value[0], sentences.value[1]),
|
sentencePerParagraph: randIntFromInterval(sentences.value[0], sentences.value[1]),
|
||||||
wordCount: randIntFromInterval(words.value[0], words.value[1]),
|
wordCount: randIntFromInterval(words.value[0], words.value[1]),
|
||||||
startWithLoremIpsum: startWithLoremIpsum.value,
|
startWithLoremIpsum: startWithLoremIpsum.value,
|
||||||
|
language: language.value,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
|
const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to the clipboard' });
|
||||||
|
@ -23,6 +28,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<c-card>
|
<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-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-slider v-model:value="paragraphs" :step="1" :min="1" :max="20" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
@ -41,10 +53,13 @@ const { copy } = useCopy({ source: loremIpsumText, text: 'Lorem ipsum copied to
|
||||||
|
|
||||||
<c-input-text :value="loremIpsumText" multiline placeholder="Your lorem ipsum..." readonly mt-5 rows="5" />
|
<c-input-text :value="loremIpsumText" multiline placeholder="Your lorem ipsum..." readonly mt-5 rows="5" />
|
||||||
|
|
||||||
<div mt-5 flex justify-center>
|
<div mt-5 flex justify-center gap-3>
|
||||||
<c-button autofocus @click="copy()">
|
<c-button autofocus @click="copy()">
|
||||||
Copy
|
Copy
|
||||||
</c-button>
|
</c-button>
|
||||||
|
<c-button @click="refreshLoremIpsum">
|
||||||
|
Refresh
|
||||||
|
</c-button>
|
||||||
</div>
|
</div>
|
||||||
</c-card>
|
</c-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
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…
Add table
Add a link
Reference in a new issue