mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
commit
713c10db74
11 changed files with 246 additions and 42 deletions
|
@ -43,6 +43,8 @@
|
||||||
"@tauri-apps/api": "^1.2.0",
|
"@tauri-apps/api": "^1.2.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lorem-ipsum": "^2.0.8",
|
||||||
"svelte-watch-resize": "^1.0.3"
|
"svelte-watch-resize": "^1.0.3"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
|
|
|
@ -1,6 +1,47 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '$appcss';
|
import '$appcss';
|
||||||
import Placeholder from '$components/Placeholder/Placeholder.svelte';
|
import { afterUpdate } from 'svelte';
|
||||||
|
import ReviewCard from '@tea/ui/ReviewCard/ReviewCard.svelte';
|
||||||
|
|
||||||
|
import type { Review } from '@tea/ui/types';
|
||||||
|
export let reviews: Review[];
|
||||||
|
|
||||||
|
const getColReviews = (n: number) => {
|
||||||
|
return reviews.filter((_item, i) => (i - n) % 3 === 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
let col1: Review[] = [];
|
||||||
|
let col2: Review[] = [];
|
||||||
|
let col3: Review[] = [];
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
col1 = getColReviews(0);
|
||||||
|
col2 = getColReviews(1);
|
||||||
|
col3 = getColReviews(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: problem with reviews with differing heights
|
||||||
|
// ideally they should work like metro-ui to not have extreme height diff between columns
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Placeholder label="PackageReviews" />
|
<header class="text-primary bg-black border border-gray p-4">REVIEWS ({reviews.length})</header>
|
||||||
|
<section class="flex flex-wrap bg-black flex-row font-machina">
|
||||||
|
<div class="border-gray border-0 border-l-2 p-4 w-1/3">
|
||||||
|
{#each col1 as review}
|
||||||
|
<ReviewCard {review} />
|
||||||
|
<div class="mt-4" />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div class="border-gray border-0 border-l-2 p-4 w-1/3">
|
||||||
|
{#each col2 as review}
|
||||||
|
<ReviewCard {review} />
|
||||||
|
<div class="mt-4" />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<div class="border-gray border-0 p-4 border-x-2 w-1/3">
|
||||||
|
{#each col3 as review}
|
||||||
|
<ReviewCard {review} />
|
||||||
|
<div class="mt-4" />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
const searchLimit = 5;
|
const searchLimit = 5;
|
||||||
|
|
||||||
const setPackages = (pkgs: Package[]) => {
|
const setPackages = (pkgs: Package[]) => {
|
||||||
|
console.log('pkgs sub', pkgs);
|
||||||
packages = pkgs.sort((a, b) => {
|
packages = pkgs.sort((a, b) => {
|
||||||
if (sortBy === 'popularity') {
|
if (sortBy === 'popularity') {
|
||||||
const aPop = +a.dl_count + a.installs;
|
const aPop = +a.dl_count + a.installs;
|
||||||
|
@ -36,9 +37,12 @@
|
||||||
packagesStore.subscribe((v) => {
|
packagesStore.subscribe((v) => {
|
||||||
allPackages = v;
|
allPackages = v;
|
||||||
setPackages(allPackages);
|
setPackages(allPackages);
|
||||||
packagesIndex = new Fuse(allPackages, {
|
if (!packagesIndex) {
|
||||||
keys: ['name', 'full_name', 'desc']
|
// dont remove or this can get crazy
|
||||||
});
|
packagesIndex = new Fuse(allPackages, {
|
||||||
|
keys: ['name', 'full_name', 'desc']
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
* TODO:
|
* TODO:
|
||||||
* * make cors work with api.tea.xyz/v1
|
* * make cors work with api.tea.xyz/v1
|
||||||
*/
|
*/
|
||||||
import type { Package } from '../types';
|
import type { Package, Review } from '@tea/ui/types';
|
||||||
|
import { loremIpsum } from 'lorem-ipsum';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
const packages: Package[] = [
|
const packages: Package[] = [
|
||||||
{
|
{
|
||||||
slug: 'mesonbuild_com',
|
slug: 'mesonbuild_com',
|
||||||
|
@ -156,3 +159,41 @@ export async function getPackages(): Promise<Package[]> {
|
||||||
export async function getFeaturedPackages(): Promise<Package[]> {
|
export async function getFeaturedPackages(): Promise<Package[]> {
|
||||||
return packages.slice(0, 4);
|
return packages.slice(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getPackageReviews(full_name: string): Promise<Review[]> {
|
||||||
|
console.log(`generating reviews for ${full_name}`);
|
||||||
|
|
||||||
|
const reviewCount = _.random(7, 21);
|
||||||
|
const reviews: Review[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < reviewCount; i++) {
|
||||||
|
const title = loremIpsum({
|
||||||
|
count: _.random(2, 5),
|
||||||
|
format: 'plain',
|
||||||
|
paragraphLowerBound: 3,
|
||||||
|
paragraphUpperBound: 7,
|
||||||
|
random: Math.random,
|
||||||
|
sentenceLowerBound: 5,
|
||||||
|
sentenceUpperBound: 15,
|
||||||
|
units: 'words'
|
||||||
|
});
|
||||||
|
const comment = loremIpsum({
|
||||||
|
count: 2,
|
||||||
|
format: 'plain',
|
||||||
|
paragraphLowerBound: 3,
|
||||||
|
paragraphUpperBound: 7,
|
||||||
|
random: Math.random,
|
||||||
|
sentenceLowerBound: 5,
|
||||||
|
sentenceUpperBound: 15,
|
||||||
|
units: 'sentences'
|
||||||
|
});
|
||||||
|
const rating = _.random(0, 5);
|
||||||
|
reviews.push({
|
||||||
|
title,
|
||||||
|
comment,
|
||||||
|
rating
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return reviews;
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
*/
|
*/
|
||||||
import { getClient } from '@tauri-apps/api/http';
|
import { getClient } from '@tauri-apps/api/http';
|
||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer';
|
||||||
import type { Package } from '../types';
|
import type { Package, Review } from '../types';
|
||||||
import * as mock from './mock';
|
import * as mock from './mock';
|
||||||
|
|
||||||
const username = 'user';
|
const username = 'user';
|
||||||
|
@ -55,3 +55,10 @@ export async function getFeaturedPackages(): Promise<Package[]> {
|
||||||
const packages = await mock.getFeaturedPackages();
|
const packages = await mock.getFeaturedPackages();
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getPackageReviews(full_name: string): Promise<Review[]> {
|
||||||
|
console.log(`getting reviews for ${full_name}`);
|
||||||
|
const reviews: Review[] = await mock.getPackageReviews(full_name);
|
||||||
|
|
||||||
|
return reviews;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import type { Package } from './types';
|
import type { Package, Review } from '@tea/ui/types';
|
||||||
|
|
||||||
import { getPackages, getFeaturedPackages } from '@api';
|
// TODO: figure out a better structure for managing states maybe turn them into models?
|
||||||
|
|
||||||
|
import { getPackages, getFeaturedPackages, getPackageReviews } from '@api';
|
||||||
|
|
||||||
export const backLink = writable<string>('/');
|
export const backLink = writable<string>('/');
|
||||||
|
|
||||||
|
@ -10,11 +12,51 @@ export const packages = writable<Package[]>([]);
|
||||||
export const featuredPackages = writable<Package[]>([]);
|
export const featuredPackages = writable<Package[]>([]);
|
||||||
|
|
||||||
export const initializePackages = async () => {
|
export const initializePackages = async () => {
|
||||||
|
console.log('initialize packages');
|
||||||
const newPackages = await getPackages();
|
const newPackages = await getPackages();
|
||||||
packages.set(newPackages);
|
packages.set(newPackages);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initializeFeaturedPackages = async () => {
|
export const initializeFeaturedPackages = async () => {
|
||||||
|
console.log('initialzie featured packages');
|
||||||
const packages = await getFeaturedPackages();
|
const packages = await getFeaturedPackages();
|
||||||
featuredPackages.set(packages);
|
featuredPackages.set(packages);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface PackagesReview {
|
||||||
|
[full_name: string]: Review[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function initPackagesReviewStore() {
|
||||||
|
const { set, update, subscribe } = writable<PackagesReview>({});
|
||||||
|
|
||||||
|
let packagesReviews: PackagesReview = {};
|
||||||
|
|
||||||
|
subscribe((v) => (packagesReviews = v));
|
||||||
|
|
||||||
|
const getSetPackageReviews = async (full_name: string) => {
|
||||||
|
if (full_name && !packagesReviews[full_name]) {
|
||||||
|
console.log('getting reviews for', full_name);
|
||||||
|
const reviews = await getPackageReviews(full_name);
|
||||||
|
update((v) => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
[full_name]: reviews
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe: (full_name: string, reset: (reviews: Review[]) => void) => {
|
||||||
|
getSetPackageReviews(full_name);
|
||||||
|
return subscribe((value) => {
|
||||||
|
if (value[full_name]) {
|
||||||
|
reset(value[full_name]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const packagesReviewStore = initPackagesReviewStore();
|
||||||
|
|
|
@ -9,17 +9,24 @@
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
import { packages, featuredPackages } from '$libs/stores';
|
import { packages, featuredPackages, packagesReviewStore } from '$libs/stores';
|
||||||
|
|
||||||
import type { Package } from '@tea/ui/types';
|
import type { Package, Review } from '@tea/ui/types';
|
||||||
|
|
||||||
let pkg: Package;
|
let pkg: Package;
|
||||||
|
|
||||||
|
let reviews: Review[];
|
||||||
|
|
||||||
const setPkg = (pkgs: Package[]) => {
|
const setPkg = (pkgs: Package[]) => {
|
||||||
const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package;
|
const foundPackage = pkgs.find(({ slug }) => slug === data?.slug) as Package;
|
||||||
if (!pkg && foundPackage) {
|
if (!pkg && foundPackage) {
|
||||||
pkg = foundPackage;
|
pkg = foundPackage;
|
||||||
}
|
}
|
||||||
|
if (!reviews && pkg) {
|
||||||
|
packagesReviewStore.subscribe(pkg.full_name, (updatedReviews) => {
|
||||||
|
reviews = updatedReviews;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.subscribe(setPkg);
|
packages.subscribe(setPkg);
|
||||||
|
@ -32,6 +39,6 @@
|
||||||
<PackageBanner {pkg} />
|
<PackageBanner {pkg} />
|
||||||
</section>
|
</section>
|
||||||
<section class="mt-8">
|
<section class="mt-8">
|
||||||
<PackageReviews />
|
<PackageReviews reviews={reviews || []} />
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
30
packages/ui/src/ReviewCard/ReviewCard.stories.ts
Normal file
30
packages/ui/src/ReviewCard/ReviewCard.stories.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import ReviewCard from './ReviewCard.svelte';
|
||||||
|
|
||||||
|
// More on how to set up stories at: https://storybook.js.org/docs/7.0/svelte/writing-stories/introduction
|
||||||
|
export default {
|
||||||
|
title: 'Example/ReviewCard',
|
||||||
|
component: ReviewCard,
|
||||||
|
tags: ['docsPage'],
|
||||||
|
render: ({ review }) => ({
|
||||||
|
Component: ReviewCard,
|
||||||
|
props: { review }
|
||||||
|
}),
|
||||||
|
argTypes: {
|
||||||
|
review: {
|
||||||
|
name: 'review',
|
||||||
|
description: 'this is type Review'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// More on writing stories with args: https://storybook.js.org/docs/7.0/svelte/writing-stories/args
|
||||||
|
export const Example = {
|
||||||
|
args: {
|
||||||
|
review: {
|
||||||
|
title: 'installing tea',
|
||||||
|
comment:
|
||||||
|
'Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas, voluptatum molestiae esse quisquam earum debitis.',
|
||||||
|
rating: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
35
packages/ui/src/ReviewCard/ReviewCard.svelte
Normal file
35
packages/ui/src/ReviewCard/ReviewCard.svelte
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<script type="ts">
|
||||||
|
import '../app.css';
|
||||||
|
import type { Review } from '../types';
|
||||||
|
|
||||||
|
export let review: Review;
|
||||||
|
|
||||||
|
const getStarType = () => {
|
||||||
|
let star = 'full';
|
||||||
|
if (review.rating < 3) {
|
||||||
|
star = 'empty';
|
||||||
|
} else if (review.rating < 4) {
|
||||||
|
star = 'half';
|
||||||
|
}
|
||||||
|
return `icon-star-${star}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStarLabel = () => {
|
||||||
|
let label = 'DELIGHTFUL';
|
||||||
|
if (review.rating < 3) {
|
||||||
|
label = 'NOT DELIGHTFUL';
|
||||||
|
} else if (review.rating < 4) {
|
||||||
|
label = 'DELIGHTFUL WITH NOTES';
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="border border-gray p-4">
|
||||||
|
<header class=" text-primary text-lg">{review.title}</header>
|
||||||
|
<div class="flex mt-2 text-xs">
|
||||||
|
<i class={`${getStarType()} text-primary`} />
|
||||||
|
<span class="text-gray pl-2">{getStarLabel()}</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 text-sm">{review.comment}</p>
|
||||||
|
</section>
|
|
@ -1,3 +1,9 @@
|
||||||
|
export interface Review {
|
||||||
|
title: string;
|
||||||
|
comment: string;
|
||||||
|
rating: number;
|
||||||
|
created_at?: Date | string;
|
||||||
|
}
|
||||||
export interface Package {
|
export interface Package {
|
||||||
slug: string;
|
slug: string;
|
||||||
version: string;
|
version: string;
|
||||||
|
@ -11,4 +17,5 @@ export interface Package {
|
||||||
desc: string;
|
desc: string;
|
||||||
dl_count: number;
|
dl_count: number;
|
||||||
installs: number;
|
installs: number;
|
||||||
|
reviews?: Review[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ importers:
|
||||||
eslint-config-prettier: ^8.3.0
|
eslint-config-prettier: ^8.3.0
|
||||||
eslint-plugin-svelte3: ^4.0.0
|
eslint-plugin-svelte3: ^4.0.0
|
||||||
fuse.js: ^6.6.2
|
fuse.js: ^6.6.2
|
||||||
|
lodash: ^4.17.21
|
||||||
|
lorem-ipsum: ^2.0.8
|
||||||
postcss: ^8.4.19
|
postcss: ^8.4.19
|
||||||
prettier: ^2.6.2
|
prettier: ^2.6.2
|
||||||
prettier-plugin-svelte: ^2.7.0
|
prettier-plugin-svelte: ^2.7.0
|
||||||
|
@ -38,12 +40,14 @@ importers:
|
||||||
'@tauri-apps/api': 1.2.0
|
'@tauri-apps/api': 1.2.0
|
||||||
buffer: 6.0.3
|
buffer: 6.0.3
|
||||||
fuse.js: 6.6.2
|
fuse.js: 6.6.2
|
||||||
|
lodash: 4.17.21
|
||||||
|
lorem-ipsum: 2.0.8
|
||||||
svelte-watch-resize: 1.0.3
|
svelte-watch-resize: 1.0.3
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@playwright/test': 1.25.0
|
'@playwright/test': 1.25.0
|
||||||
'@sveltejs/adapter-auto': 1.0.0-next.90
|
'@sveltejs/adapter-auto': 1.0.0-next.90
|
||||||
'@sveltejs/adapter-static': 1.0.0-next.48
|
'@sveltejs/adapter-static': 1.0.0-next.48
|
||||||
'@sveltejs/kit': 1.0.0-next.567_svelte@3.53.1+vite@3.2.4
|
'@sveltejs/kit': 1.0.0-next.570_svelte@3.53.1+vite@3.2.4
|
||||||
'@tauri-apps/cli': 1.2.0
|
'@tauri-apps/cli': 1.2.0
|
||||||
'@tea/ui': link:../ui
|
'@tea/ui': link:../ui
|
||||||
'@typescript-eslint/eslint-plugin': 5.43.0_wze2rj5tow7zwqpgbdx2buoy3m
|
'@typescript-eslint/eslint-plugin': 5.43.0_wze2rj5tow7zwqpgbdx2buoy3m
|
||||||
|
@ -3206,34 +3210,6 @@ packages:
|
||||||
resolution: {integrity: sha512-Z5Z+QZOav6D0KDeU3ReksGERJg/sX1k5OKWWXyQ11OwGErEEwSXHYRUyjaBmZEPeGzpVVGwwMUK8YWJlG/MKeA==}
|
resolution: {integrity: sha512-Z5Z+QZOav6D0KDeU3ReksGERJg/sX1k5OKWWXyQ11OwGErEEwSXHYRUyjaBmZEPeGzpVVGwwMUK8YWJlG/MKeA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@sveltejs/kit/1.0.0-next.567_svelte@3.53.1+vite@3.2.4:
|
|
||||||
resolution: {integrity: sha512-4Q74HPLZb9Rr60n7EJANXH2Ng3d7wwrz67TuXxVfYuxARigWO9YzjcLHxG2IVMwRZIeT+LlwOKkg9vYYdBiezQ==}
|
|
||||||
engines: {node: '>=16.14'}
|
|
||||||
hasBin: true
|
|
||||||
requiresBuild: true
|
|
||||||
peerDependencies:
|
|
||||||
svelte: ^3.44.0
|
|
||||||
vite: ^3.2.0
|
|
||||||
dependencies:
|
|
||||||
'@sveltejs/vite-plugin-svelte': 1.3.1_svelte@3.53.1+vite@3.2.4
|
|
||||||
'@types/cookie': 0.5.1
|
|
||||||
cookie: 0.5.0
|
|
||||||
devalue: 4.2.0
|
|
||||||
kleur: 4.1.5
|
|
||||||
magic-string: 0.26.7
|
|
||||||
mime: 3.0.0
|
|
||||||
sade: 1.8.1
|
|
||||||
set-cookie-parser: 2.5.1
|
|
||||||
sirv: 2.0.2
|
|
||||||
svelte: 3.53.1
|
|
||||||
tiny-glob: 0.2.9
|
|
||||||
undici: 5.13.0
|
|
||||||
vite: 3.2.4
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- diff-match-patch
|
|
||||||
- supports-color
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@sveltejs/kit/1.0.0-next.570_svelte@3.53.1+vite@3.2.4:
|
/@sveltejs/kit/1.0.0-next.570_svelte@3.53.1+vite@3.2.4:
|
||||||
resolution: {integrity: sha512-7CUoYidoWlKdTGxL/5RsPPkgGTb36TwFBnhSZmspHFeiIST5qQEXyzqicFk8+4M5qQhxvOZ0NuP8uy7Pc+xf/Q==}
|
resolution: {integrity: sha512-7CUoYidoWlKdTGxL/5RsPPkgGTb36TwFBnhSZmspHFeiIST5qQEXyzqicFk8+4M5qQhxvOZ0NuP8uy7Pc+xf/Q==}
|
||||||
engines: {node: '>=16.14'}
|
engines: {node: '>=16.14'}
|
||||||
|
@ -4634,6 +4610,11 @@ packages:
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/commander/9.4.1:
|
||||||
|
resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==}
|
||||||
|
engines: {node: ^12.20.0 || >=14}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/commondir/1.0.1:
|
/commondir/1.0.1:
|
||||||
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -7341,7 +7322,6 @@ packages:
|
||||||
|
|
||||||
/lodash/4.17.21:
|
/lodash/4.17.21:
|
||||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/longest-streak/3.1.0:
|
/longest-streak/3.1.0:
|
||||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||||
|
@ -7354,6 +7334,14 @@ packages:
|
||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/lorem-ipsum/2.0.8:
|
||||||
|
resolution: {integrity: sha512-5RIwHuCb979RASgCJH0VKERn9cQo/+NcAi2BMe9ddj+gp7hujl6BI+qdOG4nVsLDpwWEJwTVYXNKP6BGgbcoGA==}
|
||||||
|
engines: {node: '>= 8.x', npm: '>= 5.x'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
commander: 9.4.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lower-case/2.0.2:
|
/lower-case/2.0.2:
|
||||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in a new issue