diff --git a/package-lock.json b/package-lock.json index ec6922e..62ea0e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,8 @@ "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-navigation-menu": "^1.2.1", "@radix-ui/react-slot": "^1.1.0", + "@types/canvas-confetti": "^1.6.4", + "canvas-confetti": "^1.9.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "framer-motion": "^11.11.17", @@ -1185,6 +1187,12 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/canvas-confetti": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@types/canvas-confetti/-/canvas-confetti-1.6.4.tgz", + "integrity": "sha512-fNyZ/Fdw/Y92X0vv7B+BD6ysHL4xVU5dJcgzgxLdGbn8O3PezZNIJpml44lKM0nsGur+o/6+NZbZeNTt00U1uA==", + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "dev": true, @@ -1808,6 +1816,16 @@ ], "license": "CC-BY-4.0" }, + "node_modules/canvas-confetti": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", + "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", + "license": "ISC", + "funding": { + "type": "donate", + "url": "https://www.paypal.me/kirilvatev" + } + }, "node_modules/chalk": { "version": "4.1.2", "dev": true, diff --git a/package.json b/package.json index 9e5e4c4..0e32926 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-navigation-menu": "^1.2.1", "@radix-ui/react-slot": "^1.1.0", + "@types/canvas-confetti": "^1.6.4", + "canvas-confetti": "^1.9.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "framer-motion": "^11.11.17", diff --git a/public/images/hero-title-left.svg b/public/images/hero-title-left.svg new file mode 100644 index 0000000..5bc44ed --- /dev/null +++ b/public/images/hero-title-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/hero-title-right.svg b/public/images/hero-title-right.svg new file mode 100644 index 0000000..08118c5 --- /dev/null +++ b/public/images/hero-title-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/light-effect.svg b/public/images/light-effect.svg new file mode 100644 index 0000000..2592aa6 --- /dev/null +++ b/public/images/light-effect.svg @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/logo-darkmode.svg b/public/images/logo-darkmode.svg new file mode 100644 index 0000000..d947b7f --- /dev/null +++ b/public/images/logo-darkmode.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/images/logo-without-text-white.svg b/public/images/logo-without-text-white.svg new file mode 100644 index 0000000..fad239d --- /dev/null +++ b/public/images/logo-without-text-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/logo-without-text.svg b/public/images/logo-without-text.svg new file mode 100644 index 0000000..d5f2100 --- /dev/null +++ b/public/images/logo-without-text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/right-circle-hero.svg b/public/images/right-circle-hero.svg new file mode 100644 index 0000000..8b2877b --- /dev/null +++ b/public/images/right-circle-hero.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/top-left-circle-hero.svg b/public/images/top-left-circle-hero.svg new file mode 100644 index 0000000..b0724c5 --- /dev/null +++ b/public/images/top-left-circle-hero.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6699ebb..789e09a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -35,7 +35,6 @@ export default function RootLayout({ >
diff --git a/src/app/page.tsx b/src/app/page.tsx index 0144ee2..b9a9f79 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,503 +1,476 @@ import { Button } from '@/components/ui/button' import { CoolMode } from '@/components/ui/cool-mode' +import HeroSection from '@/components/ui/hero' import WordPullUp from '@/components/ui/word-pull-up' import Image from 'next/image' export default function Home() { return ( - <> -
-
- - Next.js logo - - - - -
    -
  1. - Get started by editing{' '} - - src/app/page.tsx - - . -
  2. -
  3. Save and see your changes instantly.
  4. -
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam - tempor quam id ante mattis tristique. Donec eget pretium mauris, et - efficitur turpis. Donec faucibus ex urna, id sagittis massa luctus - id. Nam at est ac turpis tincidunt maximus. Aenean porta ex vitae - diam viverra molestie. Aliquam ac mollis nibh. Suspendisse at mauris - dapibus, volutpat justo et, rhoncus nibh. Mauris laoreet tempor - velit, eu bibendum orci sodales et. Nam lacinia pulvinar euismod. Ut - nulla felis, interdum vel arcu eget, blandit suscipit nulla. Proin - non eleifend felis. Nunc in magna ex. Etiam quam neque, lacinia vel - augue eu, consectetur hendrerit massa. Nam rutrum erat augue, a - aliquam mi vulputate nec. Quisque non erat laoreet, ultrices nibh - quis, dictum metus. Vivamus luctus lobortis metus, nec finibus odio - laoreet quis. Donec vel porttitor velit, sit amet pellentesque leo. - Fusce egestas iaculis quam, at blandit tellus molestie nec. In sit - amet aliquam nisi. Cras in lacus nec dui blandit semper in a diam. - Integer vel elit convallis, interdum eros sed, condimentum turpis. - Nunc mauris sapien, porta ac sapien eget, consequat sollicitudin - urna. Maecenas accumsan sagittis nibh nec venenatis. Praesent - convallis lectus consequat vestibulum blandit. Sed scelerisque quam - a egestas commodo. Fusce vulputate arcu nunc, quis scelerisque quam - viverra faucibus. Ut aliquam dignissim metus eu sollicitudin. Morbi - turpis nibh, tempus eget libero eu, lobortis efficitur lacus. - Praesent tempor pellentesque diam vitae molestie. Morbi quis - volutpat quam, sed placerat tortor. Vestibulum efficitur quam vel - sem lacinia placerat. Duis eu nisl pellentesque, auctor mauris quis, - porttitor nunc. Nam vehicula consectetur libero, quis volutpat felis - luctus non. Maecenas id sagittis lectus. Sed dignissim nisl nunc, - vel finibus libero accumsan a. Sed tempus, tortor non ullamcorper - sodales, ipsum lorem imperdiet lacus, gravida finibus dui libero non - lectus. Cras ex odio, feugiat vel pharetra feugiat, rutrum nec ante. - Maecenas elit arcu, ultrices non semper ut, rutrum ut nisi. Vivamus - a sem nec lorem viverra dignissim. Aliquam ac mauris eget odio - convallis viverra vulputate bibendum arcu. Nunc vel diam ac ipsum - aliquet interdum. Donec nisi metus, facilisis vitae arcu id, tempor - aliquet libero. Morbi iaculis mi urna. Aenean dui risus, rutrum at - luctus eget, ultrices in enim. Donec maximus dictum aliquet. Vivamus - non velit odio. Ut odio mauris, rhoncus a turpis at, viverra - fringilla tortor. Vivamus pellentesque, orci vitae fringilla - gravida, eros justo pharetra diam, et aliquam neque felis in nibh. - Sed finibus mattis magna, vitae molestie est scelerisque eget. - Praesent aliquam vehicula ipsum id finibus. Aenean lorem augue, - dapibus ac diam sed, semper sagittis ex. Proin congue diam in - elementum condimentum. Praesent et imperdiet mauris, quis consequat - est. Nunc eros velit, posuere quis est vitae, luctus pellentesque - quam. Interdum et malesuada fames ac ante ipsum primis in faucibus. - Vivamus porttitor neque ipsum, vel dictum nulla viverra nec. Nam in - faucibus ligula. Maecenas erat purus, feugiat vel enim vel, - scelerisque feugiat erat. Vivamus justo sem, efficitur eu hendrerit - placerat, faucibus sed libero. Pellentesque euismod arcu vitae quam - eleifend tincidunt. Vestibulum vehicula nisi ut leo pellentesque - pretium. In pellentesque nisi nisi. Quisque mauris turpis, vehicula - a est et, mollis ultricies ligula. Donec quam sapien, tincidunt quis - est vitae, finibus rhoncus orci. Sed vehicula erat id accumsan - malesuada. Aliquam mollis euismod sem, a malesuada sem ultricies et. - Ut scelerisque gravida porta. Phasellus et porta ipsum, ut ultricies - nisi. Ut mattis tellus id justo pellentesque, sed rhoncus dui - feugiat. Sed quis tortor a arcu varius dapibus ac vitae odio. - Vivamus pellentesque ipsum at justo tempor, scelerisque interdum - neque mattis. Nam pellentesque rhoncus justo in rutrum. Nunc varius - vel lacus at pellentesque. Mauris vel porta arcu. Lorem ipsum dolor - sit amet, consectetur adipiscing elit. Suspendisse pretium mi mollis - laoreet iaculis. Donec tincidunt purus vel blandit mattis. - Vestibulum sodales consectetur mauris, ac malesuada enim ultricies - id. Mauris mollis sed est eu ultrices. Donec ante dolor, fringilla - vitae leo non, lacinia euismod libero. Donec risus sapien, sodales - tempus lectus ut, dignissim molestie arcu. Fusce lacinia a risus - eget tincidunt. Nunc auctor dignissim ultricies. Nam euismod sem in - luctus convallis. Mauris congue est id blandit consequat. Donec - lobortis dignissim risus a sagittis. Integer varius ultricies orci - ut vulputate. Etiam aliquet consectetur convallis. Nulla tempus mi - sed sagittis dapibus. In nisl mi, aliquet non facilisis at, gravida - ut dui. Nam ac massa ultricies, sodales lacus sit amet, finibus - elit. Aenean at nibh non nisl ullamcorper tincidunt eu nec arcu. - Mauris non congue est, at varius enim. Quisque et massa eleifend, - vulputate velit vitae, imperdiet arcu. Morbi ut libero dapibus, - lacinia risus in, lobortis urna. Sed quis neque eros. Pellentesque - habitant morbi tristique senectus et netus et malesuada fames ac - turpis egestas. Mauris scelerisque sodales lacus ac posuere. Quisque - sed imperdiet est. Praesent condimentum quam ac semper egestas. - Integer faucibus erat feugiat erat pulvinar, varius molestie turpis - vestibulum. Nam rutrum finibus diam, et scelerisque enim vehicula - nec. Ut lacinia risus a ipsum blandit aliquet. Sed sit amet justo - bibendum, vestibulum nisl vitae, commodo eros. Etiam nec ipsum ante. - Nullam lacinia lobortis arcu, at scelerisque arcu. Orci varius - natoque penatibus et magnis dis parturient montes, nascetur - ridiculus mus. Donec ultrices gravida sodales. Duis vestibulum elit - non consectetur ultricies. Mauris pharetra vestibulum ipsum - efficitur scelerisque. Aenean convallis gravida ex, eu interdum sem - scelerisque quis. In commodo nisi enim, id posuere sem luctus eu. - Donec tempus tristique sem. Aenean et erat leo. Etiam sapien risus, - pharetra eu tempus vel, vulputate eu massa. Nullam fringilla nibh - nulla. Nulla tristique felis purus, in placerat dolor varius at. - Etiam sed purus aliquam, tristique sem vitae, finibus diam. Vivamus - quis turpis imperdiet, viverra velit eget, mollis enim. Aliquam sit - amet mollis nunc. Phasellus eu nisi eu mi commodo porttitor. Vivamus - tellus dolor, porttitor a leo vitae, bibendum bibendum eros. - Pellentesque sagittis varius nisi, non imperdiet felis. Aliquam orci - quam, vestibulum quis diam sed, molestie semper ante. Nulla - facilisi. Cras ac libero lacus. Orci varius natoque penatibus et - magnis dis parturient montes, nascetur ridiculus mus. Sed fermentum, - massa nec finibus venenatis, risus mi molestie justo, pellentesque - eleifend velit dui faucibus elit. Sed lacinia nisi sed mi venenatis - egestas. Mauris vulputate eleifend scelerisque. Donec vitae nisi in - sem congue maximus. Nam vulputate aliquet malesuada. Fusce dolor - neque, cursus laoreet mi eu, ullamcorper scelerisque leo. Proin eu - nibh ipsum. Fusce pharetra quis tellus sit amet ornare. Curabitur - luctus semper augue nec ornare. Cras suscipit non augue ac bibendum. - Quisque sed arcu enim. Sed in mollis nisi. Quisque at mattis felis. - Nunc dapibus a orci a semper. Proin venenatis nec odio at bibendum. - Cras feugiat diam ac justo porttitor, ac molestie nibh gravida. - Donec molestie commodo mi, sed porttitor erat lacinia vitae. - Vestibulum placerat venenatis dignissim. Maecenas mollis neque enim, - a congue magna commodo sed. Morbi tincidunt sapien ac egestas - accumsan. Quisque sit amet eros tortor. Donec ac purus massa. - Quisque sodales aliquet ligula, ac tempus purus mollis in. Donec id - hendrerit tortor. Fusce eget turpis at nisl porttitor dictum. - Quisque aliquam dapibus justo, id porta nunc fringilla id. Nullam id - tristique nunc. Praesent vehicula odio metus, non congue nunc varius - quis. Vivamus euismod scelerisque dui id tempus. Curabitur luctus, - nisi in pellentesque dictum, nunc ex elementum orci, vitae fermentum - urna libero congue libero. Nunc lacinia porttitor odio, id pharetra - urna vulputate in. Aenean suscipit at nunc in sagittis. Donec - bibendum lorem in pellentesque dapibus. Vestibulum et nibh et risus - pellentesque viverra ac vitae augue. Donec nec accumsan nulla, et - faucibus purus. Donec quis dapibus erat. Suspendisse sapien libero, - ultricies vel lacinia vel, interdum at ante. Nam molestie convallis - malesuada. Donec mattis faucibus est ac facilisis. Vestibulum - venenatis justo at diam luctus maximus. Praesent molestie - ullamcorper odio. Nulla suscipit ligula nisl. Suspendisse imperdiet - finibus urna, sit amet iaculis felis faucibus ac. Curabitur ut erat - sed ipsum hendrerit aliquam eu et felis. Fusce malesuada mi a ante - interdum semper. Curabitur pretium elementum magna, eu maximus diam - condimentum vitae. Morbi vehicula a diam id volutpat. Ut eu bibendum - lacus, in feugiat neque. Nullam luctus nisi vitae tempus sagittis. - Nunc nec turpis vestibulum, consequat nulla in, eleifend tellus. - Etiam tristique risus urna, ac rhoncus turpis sollicitudin at. - Curabitur accumsan sapien non felis dictum, eu euismod metus - volutpat. Aenean sollicitudin nibh tincidunt dui porta viverra. - Proin id odio ut felis volutpat luctus eget eu sapien. Orci varius - natoque penatibus et magnis dis parturient montes, nascetur - ridiculus mus. Phasellus iaculis euismod metus sagittis laoreet. - Vestibulum ante ipsum primis in faucibus orci luctus et ultrices - posuere cubilia curae; Proin sed dictum nisl. Mauris in dapibus - eros. Phasellus tristique sodales libero at malesuada. Nunc vel - tortor vel sapien tincidunt tristique sit amet vitae nunc. Praesent - porttitor ex a tortor finibus vehicula. Donec congue malesuada elit, - facilisis ultrices nunc pellentesque at. Suspendisse iaculis et - lacus vel volutpat. Etiam id neque ac turpis porttitor finibus. - Curabitur sed malesuada felis. Nullam vel tellus a massa eleifend - euismod. Proin tristique efficitur massa, at egestas mauris semper - vel. Sed commodo consectetur erat ac iaculis. Proin facilisis - gravida facilisis. In condimentum augue lectus, nec ultricies ipsum - egestas sit amet. Curabitur at gravida nulla, ac mollis sapien. - Mauris rutrum, sem nec sollicitudin tincidunt, lacus magna tristique - nisl, vel faucibus felis nisl vitae justo. Nam congue pretium - tincidunt. Praesent pharetra, enim sit amet mollis blandit, diam - tellus interdum tellus, at mattis erat ipsum a erat. Cras finibus - fringilla turpis, eget facilisis odio placerat vel. Cras tincidunt - sed enim at laoreet. Duis vel blandit orci. Quisque congue tincidunt - ligula quis tempor. Fusce ante nunc, dictum at suscipit vel, lacinia - ut est. Morbi sagittis, mi a convallis faucibus, ante libero dictum - ante, placerat pulvinar eros massa sed felis. Suspendisse facilisis - luctus posuere. Curabitur sed sagittis urna. Suspendisse vel feugiat - orci, ut mollis dui. Maecenas efficitur, ante tristique blandit - cursus, neque ligula mollis nisl, in gravida nunc libero id tortor. - Pellentesque sit amet rutrum diam, eget pulvinar mi. Morbi dolor - magna, rutrum at quam quis, pretium consectetur nisi. Class aptent - taciti sociosqu ad litora torquent per conubia nostra, per inceptos - himenaeos. Fusce varius enim quis nibh sodales, ac semper velit - volutpat. Phasellus a eros vitae quam dignissim lacinia. Praesent - tellus ante, hendrerit auctor ornare id, accumsan id nulla. Nam - vitae elit quis purus porttitor mattis et et orci. Suspendisse magna - est, ullamcorper quis mollis ac, dapibus eget mauris. Vestibulum - diam arcu, aliquam eget mauris eu, consectetur hendrerit risus. Ut - congue sem ante, eu vestibulum nibh luctus in. Proin aliquet justo - mi, ut tincidunt tellus scelerisque et. Duis maximus orci nec elit - maximus consequat. Mauris at consectetur mi. Phasellus convallis leo - non ultricies tempus. Nam id metus placerat purus vulputate feugiat. - Aenean mattis sem tempus massa viverra consequat. Class aptent - taciti sociosqu ad litora torquent per conubia nostra, per inceptos - himenaeos. Integer a est tristique, sagittis justo ut, bibendum - nunc. Morbi ullamcorper metus mauris, eu vehicula mauris - pellentesque quis. Vivamus bibendum sapien vitae quam pulvinar, nec - eleifend metus faucibus. Aliquam sed dui vitae nulla euismod - ullamcorper. Mauris accumsan volutpat orci in ultrices. Aenean sit - amet urna quis erat efficitur malesuada. Suspendisse ac quam - aliquet, venenatis eros ut, mollis elit. Nunc aliquam pharetra nisl - ut sodales. Cras imperdiet fermentum mauris at maximus. Nunc at - libero ac massa volutpat viverra ac at mauris. Fusce ut consequat - est, sit amet placerat est. Etiam tincidunt at neque id porta. In - hac habitasse platea dictumst. Vestibulum maximus mollis nisl, vitae - pulvinar lacus suscipit a. Nulla finibus ut mauris vitae - sollicitudin. In in consectetur diam, sed faucibus justo. Proin quis - libero et neque luctus eleifend. Aliquam volutpat maximus nulla, at - accumsan risus molestie at. Lorem ipsum dolor sit amet, consectetur - adipiscing elit. Donec id interdum eros. Pellentesque ut massa id - libero euismod tempus ut nec risus. Pellentesque rutrum lorem vitae - neque tempus ultricies. Nunc tincidunt sagittis volutpat. Aliquam - erat volutpat. Aliquam erat volutpat. Quisque suscipit odio neque, - volutpat blandit diam convallis ac. Maecenas aliquam nec dui - eleifend accumsan. Suspendisse interdum dolor scelerisque nulla - porttitor, eu aliquet magna efficitur. Integer massa massa, volutpat - ac odio a, eleifend accumsan velit. Sed vitae viverra sapien, nec - mollis ex. Vestibulum vel mauris ornare, tristique magna at, - pharetra velit. Morbi hendrerit eros in gravida volutpat. Curabitur - a dignissim eros, in volutpat diam. Integer vel velit magna. Etiam - iaculis ut nibh vitae vulputate. Cras pellentesque magna lorem, in - placerat risus pharetra ut. Phasellus molestie arcu non augue - vehicula tristique. Morbi dignissim arcu risus, et tempor nulla - cursus quis. Morbi dignissim tincidunt congue. Maecenas non suscipit - metus. Etiam purus libero, sagittis id fringilla nec, pharetra quis - est. Nunc placerat a lectus quis fermentum. Nullam bibendum - ultricies diam, vitae interdum magna gravida ac. Duis malesuada - sagittis justo at ullamcorper. Aenean eros nunc, ornare ac libero - quis, laoreet accumsan mi. Sed blandit ut dolor vitae faucibus. - Donec quis ante non tellus vehicula iaculis. Suspendisse vulputate - eu orci in ullamcorper. Ut gravida augue odio, nec fermentum eros - tempus nec. Vivamus mattis lorem in lorem euismod, at vehicula - ligula dictum. Mauris ornare, ligula quis convallis pulvinar, lacus - mauris rutrum nulla, in facilisis erat tortor ut magna. Quisque - dapibus consequat tellus, at tincidunt metus finibus in. Nulla - facilisi. Suspendisse quis blandit magna, vel placerat ex. Integer - ac nunc ut tellus commodo facilisis ac vel ante. Morbi vitae felis - pretium, mollis ex at, rutrum erat. Sed justo ex, mollis sit amet - dignissim in, pharetra in lectus. Praesent porta eleifend dolor. - Donec eget velit est. Ut et sollicitudin mi. Donec vitae ipsum est. - Curabitur in felis varius, lobortis mauris in, dictum eros. Integer - nec ante vel elit gravida congue auctor in nulla. Nullam quis sapien - ut libero ultrices aliquam. Fusce in tellus et tortor bibendum - feugiat. Etiam non gravida neque. Quisque ac nibh tincidunt, varius - augue in, faucibus eros. Praesent non tempus arcu, ac commodo elit. - Nulla tempor semper elit, quis tristique justo aliquam sit amet. - Praesent eleifend ante eu nunc convallis, id posuere ligula - consequat. Nulla luctus tincidunt leo. Nam porta ac ligula eget - scelerisque. Maecenas dapibus porttitor velit. Vestibulum volutpat - eu felis et volutpat. Proin iaculis id arcu faucibus auctor. Quisque - a ultrices elit. Pellentesque sit amet tempus mauris. Morbi sem leo, - cursus sed mollis sit amet, maximus a neque. Morbi eleifend eu enim - in facilisis. Praesent eu tortor a turpis vestibulum accumsan quis - ut justo. Etiam et tempor nibh. Pellentesque blandit facilisis neque - auctor faucibus. Maecenas consectetur eget risus a fermentum. Ut sed - scelerisque quam. Aenean interdum vel dolor quis ullamcorper. Etiam - sed lectus porttitor, feugiat libero at, venenatis mauris. Vivamus - ut sapien venenatis nibh rhoncus feugiat et et orci. Duis vitae - efficitur risus. Proin quis orci dignissim, tincidunt lacus ac, - maximus diam. Cras tempor, leo sed consectetur volutpat, velit - tortor malesuada nunc, sit amet placerat felis velit id justo. - Curabitur varius nisl ut elit elementum sodales. Quisque volutpat - dui vitae elit euismod, et sodales mi pretium. Morbi sed nisl dui. - In hac habitasse platea dictumst. Morbi et tortor convallis, lacinia - lorem vitae, lacinia mauris. Integer convallis ex nisi, quis - hendrerit ipsum blandit vitae. Quisque ut velit arcu. Proin enim - leo, mollis vitae erat scelerisque, rhoncus tempor libero. In hac - habitasse platea dictumst. Sed quis purus ac orci dictum accumsan - vel consectetur ex. In gravida, justo in pharetra consequat, mauris - quam facilisis massa, vel egestas magna ex sed eros. Mauris ante - elit, auctor non urna vel, pharetra accumsan dui. Nam mollis dolor - id sem euismod, tincidunt posuere tellus malesuada. Morbi vel porta - est. Sed non enim a justo venenatis faucibus eu sit amet mauris. - Aenean quis euismod ipsum. Fusce sit amet pharetra tellus. - Suspendisse eleifend tristique mollis. Etiam non urna quis ligula - pellentesque sollicitudin. Suspendisse sit amet cursus libero. - Vivamus sed sagittis lacus. Sed dignissim ullamcorper magna eget - feugiat. Aenean vel purus sodales dui consequat imperdiet sit amet - sed ante. Praesent urna velit, vestibulum sed magna eu, tincidunt - tincidunt justo. Duis ac bibendum lectus, vel accumsan nisl. Proin - gravida massa ut pharetra ultricies. Aliquam quis gravida mauris, - sed egestas est. In at neque nisi. Morbi fringilla accumsan ex, eu - finibus velit ultrices eget. Sed tincidunt, tortor a sagittis - pharetra, leo dui tincidunt felis, eu porta arcu felis eget lacus. - Aliquam sollicitudin consequat commodo. Nam risus massa, tristique - vitae aliquam a, ullamcorper eget urna. Proin sit amet tempus - mauris. Morbi ultricies ullamcorper leo, ac blandit sapien ornare - non. Vestibulum et mi et velit ultricies vulputate. Sed aliquam - sagittis mi ut vestibulum. Etiam dictum finibus feugiat. Aenean et - laoreet felis, a porta purus. Donec pulvinar elit vitae scelerisque - suscipit. Morbi at imperdiet sem. Nam non metus quis odio gravida - porta. Nam sit amet sodales lacus. Nulla facilisi. Cras auctor - lectus a massa tempus pulvinar. Sed urna ante, tempus ut dolor sed, - sagittis suscipit odio. Nulla in venenatis nibh. Nulla tempor, dolor - ultricies interdum lacinia, nisl justo suscipit velit, eget - condimentum tellus magna sit amet dui. Cras nec vestibulum metus, - sed blandit nibh. Donec ac tempor ligula, pharetra semper tellus. In - convallis arcu quis dui euismod, bibendum lobortis leo consequat. - Morbi tincidunt lobortis mauris, et cursus sapien faucibus sit amet. - Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Pellentesque varius pellentesque egestas. Donec in ultrices lectus, - at lobortis dolor. Nunc tincidunt in nunc quis semper. Ut interdum - sollicitudin neque id gravida. Ut quis ipsum quis nisi semper - fermentum ac et orci. Etiam sollicitudin, magna non tincidunt - eleifend, sem ante sodales massa, at placerat nunc libero vel ipsum. - Vivamus a ex nec arcu tempus laoreet. Curabitur dictum ligula sed - leo euismod volutpat. Vestibulum ut interdum augue. Nunc in pulvinar - justo, vitae placerat justo. Sed ultrices luctus ligula, sit amet - tempor felis tempus sit amet. Sed feugiat ligula id nulla congue, at - sollicitudin mauris rhoncus. Ut ullamcorper semper felis non - finibus. Etiam venenatis risus ac augue eleifend, at venenatis ex - blandit. Ut ullamcorper quam magna, et pulvinar leo volutpat non. - Integer nec tellus lectus. Vestibulum ante ipsum primis in faucibus - orci luctus et ultrices posuere cubilia curae; Integer interdum - purus sagittis, sollicitudin dui eget, cursus nisi. Nulla - pellentesque vestibulum massa, et vehicula ipsum rhoncus ut. Mauris - at quam ac augue commodo pretium non vel ligula. Aliquam erat - volutpat. Suspendisse lobortis ligula ac bibendum dapibus. Quisque - feugiat condimentum elit, vitae fermentum ligula sagittis vitae. In - porttitor condimentum nunc, nec fringilla libero ultricies sed. - Mauris nulla massa, finibus nec nisi vitae, egestas congue felis. - Sed hendrerit justo vel justo pretium fermentum. Nulla dictum risus - ut scelerisque blandit. Quisque dictum pretium ullamcorper. Aliquam - dictum pretium dui nec blandit. Sed vitae nunc dui. Integer pharetra - id sem eu rutrum. Suspendisse in sagittis lorem. Phasellus eget urna - laoreet, sollicitudin metus id, mollis dolor. Duis semper pulvinar - felis, consectetur vulputate orci pharetra a. Aliquam non aliquet - ipsum. Morbi nec neque et ex pellentesque porttitor vel quis libero. - Vivamus nisl ligula, laoreet id sollicitudin in, eleifend vel - tortor. Proin aliquet, tellus volutpat lobortis varius, tortor sem - porta leo, ut imperdiet ligula quam sed nibh. Duis at augue mollis, - ultricies nunc sit amet, volutpat felis. Ut a rhoncus mi. In - ultricies ipsum vitae mi faucibus, sit amet elementum lorem iaculis. - Suspendisse ut nibh lorem. Orci varius natoque penatibus et magnis - dis parturient montes, nascetur ridiculus mus. Nulla ultrices eu ex - at aliquam. Mauris pretium ligula quis nisl eleifend cursus. Quisque - porttitor vestibulum dui, a sollicitudin dolor porttitor id. Aenean - molestie efficitur tellus a aliquam. Vivamus posuere quam nec dui - porta sagittis. Maecenas sed consequat ante. Suspendisse gravida - nisl pharetra turpis luctus sodales. Nullam condimentum quam eget - nulla scelerisque, at malesuada libero pulvinar. Nulla malesuada - augue eget sem pretium ullamcorper. Suspendisse quis erat quis sem - consequat volutpat. Quisque non eleifend ante, ac maximus neque. - Nulla id auctor massa, semper fermentum nisl. Aliquam odio metus, - convallis et sodales in, elementum vel nisi. Nunc volutpat erat - commodo augue euismod, placerat aliquam dolor aliquet. Duis - tincidunt lacinia vehicula. Aliquam erat volutpat. Vivamus consequat - bibendum fringilla. Maecenas eget nisl vitae nisl hendrerit - venenatis id ac metus. Vestibulum consectetur vitae sem eget - sollicitudin. Integer a ultricies mi, id euismod urna. Quisque in - metus ac lectus tincidunt varius vel eu quam. Cras non vehicula - nulla. Orci varius natoque penatibus et magnis dis parturient - montes, nascetur ridiculus mus. Suspendisse maximus mauris ut dolor - tincidunt, id molestie lacus accumsan. Maecenas turpis libero, - congue a tellus ut, fermentum ultricies diam. Praesent congue nulla - id vestibulum molestie. Suspendisse vitae magna ac dolor lacinia - finibus. Nullam lobortis commodo ante, ac rutrum metus cursus quis. - Orci varius natoque penatibus et magnis dis parturient montes, - nascetur ridiculus mus. Cras finibus faucibus nisi vel mattis. In - hac habitasse platea dictumst. Phasellus aliquam viverra felis, sit - amet laoreet leo fringilla et. Sed sed condimentum augue. Ut in orci - magna. Nunc condimentum erat nec purus porttitor suscipit. Nulla sed - risus sollicitudin, sagittis justo vel, pellentesque neque. - Curabitur in felis rhoncus, feugiat arcu in, aliquam urna. Vivamus - dapibus est felis, nec feugiat purus scelerisque a. Praesent sed - eros at sem ornare luctus. Donec rhoncus semper lacinia. Etiam in - placerat leo, vel bibendum massa. Pellentesque tempus neque sem, et - facilisis ligula pharetra nec. Vestibulum ante ipsum primis in - faucibus orci luctus et ultrices posuere cubilia curae; Donec at - interdum odio, et consectetur nisi. Morbi blandit volutpat enim nec - gravida. Nam lacinia dui sed dolor luctus scelerisque. Curabitur - consectetur tincidunt cursus. Quisque felis dolor, volutpat sit amet - luctus vel, volutpat sed ante. Morbi nulla tellus, luctus non semper - id, dignissim ut nisl. Fusce urna ligula, blandit ut vehicula sed, - malesuada non risus. Proin ac massa bibendum, pretium velit at, - tristique orci. Phasellus accumsan enim eget urna congue, id auctor - massa sollicitudin. Ut quis nisi sed metus placerat aliquam sed ac - sem. Integer lobortis justo lectus, vitae posuere est tristique - eget. Morbi a gravida urna. Nullam a sem a urna fermentum semper eu - quis dui. Vestibulum iaculis, ligula vitae vehicula pulvinar, nisi - ante tempor risus, eleifend vehicula quam quam eget nisi. Morbi - varius blandit varius. In lacinia neque at ante elementum, vel - hendrerit magna fringilla. Nam scelerisque nisi at sodales varius. - Class aptent taciti sociosqu ad litora torquent per conubia nostra, - per inceptos himenaeos. Nulla rhoncus arcu vitae sem elementum - ultrices. In ut placerat lorem. Praesent ut turpis orci. Duis in - egestas diam, vel efficitur turpis. Maecenas quam turpis, convallis - et eleifend non, venenatis ut tortor. Quisque vitae turpis tempor, - elementum orci eu, cursus diam. Vestibulum at sagittis nisi, eu - euismod libero. Integer eu velit commodo, gravida mi eu, rhoncus - turpis. Morbi et nulla a lacus lobortis scelerisque. Etiam rutrum - lacus nec aliquet ornare. Morbi odio dolor, pulvinar sit amet odio - sit amet, venenatis porttitor neque. Nam et laoreet elit. - Suspendisse vehicula velit quis dolor rhoncus, nec posuere tellus - sollicitudin. Aliquam erat volutpat. Sed vel tempor eros. Morbi - pulvinar ante et metus interdum eleifend. Lorem ipsum dolor sit - amet, consectetur adipiscing elit. Nullam nec ex ipsum. In id cursus - purus, nec pharetra lorem. Vestibulum enim urna, pretium in pharetra - vitae, maximus in felis. Praesent placerat euismod dolor vitae - pretium. Pellentesque habitant morbi tristique senectus et netus et - malesuada fames ac turpis egestas. Nulla quis laoreet lorem. Duis - est ipsum, tempus in nunc cursus, rutrum malesuada sapien. Nullam - condimentum, ligula non ultricies gravida, risus magna vehicula - risus, non iaculis nunc tortor ac elit. Ut consequat, velit in - luctus fringilla, urna orci efficitur diam, sed posuere urna eros ac - nunc. Nunc vel enim augue. Phasellus placerat tortor et porta - molestie. Curabitur vel arcu vitae orci congue efficitur. Integer - fermentum porttitor justo, in tristique dolor suscipit eleifend. - Nullam elementum posuere magna, vel consequat dolor pellentesque ut. - Vivamus congue lectus id arcu egestas, ac lobortis quam - sollicitudin. Nulla tempus molestie justo, et vehicula nulla - imperdiet elementum. Mauris rhoncus velit augue, vitae tincidunt - ligula elementum a. Integer tristique at lectus id ultricies. Morbi - a neque euismod tortor posuere mollis a quis nibh. Vivamus vitae - gravida metus, at tincidunt nunc. Vestibulum felis ante, ultrices - eget ornare vel, molestie sit amet mi. Nunc venenatis elementum - sagittis. Fusce venenatis dui ut risus porttitor, molestie iaculis - nulla scelerisque. Phasellus eu posuere felis, commodo aliquet est. - Vestibulum id est nec felis sollicitudin lobortis. Phasellus ac - condimentum ligula. Cras sed rutrum lacus, in cursus nibh. Duis eu - pulvinar felis. In finibus nulla in interdum venenatis. Quisque sed - felis suscipit, rhoncus dui non, condimentum sem. Nam pulvinar dolor - mollis tempus convallis. Vestibulum vulputate condimentum viverra. - Praesent pulvinar lacus sodales, convallis lacus in, consequat - velit. Ut pulvinar neque ante, at vestibulum ante posuere id. Donec - rhoncus ante at varius iaculis. Aenean molestie eros et pulvinar - consectetur. Nam convallis laoreet accumsan. Nunc vel laoreet erat. - Vivamus tristique turpis elit, non aliquam felis malesuada sed. In - eu scelerisque odio, a porttitor nulla. Pellentesque at mauris a - enim feugiat dapibus vel id dolor. In hac habitasse platea dictumst. - Morbi eget diam pretium, commodo tellus at, finibus turpis. Donec in - mauris lobortis, interdum mi vel, pharetra lectus. Phasellus justo - felis, fringilla nec lacus ac, facilisis tempor mi. Donec fringilla - risus arcu, quis eleifend leo condimentum in. Aliquam sollicitudin - cursus neque id facilisis. Nunc condimentum eros nec mi imperdiet - faucibus. Nullam luctus leo a faucibus dictum. Aenean sit amet - maximus sem. Integer in nisl finibus, accumsan turpis sed, interdum - dui. Sed pulvinar vulputate justo ut dictum. Morbi bibendum at odio - non egestas. Fusce bibendum ante vel leo convallis malesuada. Aenean - vestibulum tellus id pulvinar mattis. Pellentesque non ante - bibendum, vulputate nisl et, condimentum dui. Nam condimentum - vulputate sapien, non mattis leo lacinia at. Duis et blandit diam. - In commodo orci dolor. Fusce vehicula consectetur ante tincidunt - placerat. Nulla volutpat ante et nulla faucibus, at interdum elit - viverra. Aliquam tincidunt nulla eros, at dapibus sapien porta non. - Nunc congue tempor leo. Praesent euismod efficitur ipsum, a - sollicitudin arcu dictum sed. Sed pellentesque condimentum nunc, non - fermentum orci ultrices vitae. Phasellus sodales ultrices auctor. - Duis sed nunc quis dui tincidunt tincidunt. Proin quis viverra nisl. - Vestibulum luctus, nulla elementum porta congue, ipsum dolor - interdum ligula, nec hendrerit ipsum libero sit amet massa. Donec - vel dignissim orci. Ut finibus nisi vitae aliquet ornare. Integer - pharetra nunc id magna viverra aliquet. Mauris consequat turpis - eros, tempor sagittis tellus egestas eget. Aliquam condimentum - lectus ut aliquam vestibulum. Phasellus eget tellus ut diam - convallis iaculis eu ut mauris. Cras dignissim convallis metus, et - imperdiet diam dignissim eget. Vivamus mattis nisi eget orci - suscipit volutpat. Maecenas fermentum molestie purus in scelerisque. - Etiam at mi quis metus blandit condimentum. Suspendisse quis - molestie augue, ut bibendum tellus. Fusce nec varius ligula, in - sagittis nunc. In eget tortor vel massa varius feugiat in a lacus. - Ut feugiat tortor nibh, nec condimentum velit cursus vel. - Suspendisse non leo pretium, vestibulum dolor vitae, dictum sem. - Phasellus ut augue eu orci sodales venenatis et eu tortor. Quisque a - nunc quis tellus consectetur vestibulum. Donec vitae elit orci. Ut - volutpat vehicula diam, eget suscipit lorem tristique fermentum. In - laoreet at magna sed tincidunt. Nullam a lectus ut quam faucibus - tincidunt vitae at ante. Fusce fringilla ut felis nec ultrices. - Maecenas varius vestibulum quam, quis aliquam urna dictum at. Sed - varius lorem a metus molestie sagittis. In hac habitasse platea - dictumst. Curabitur vel orci orci. Donec lobortis massa nulla, quis - fermentum metus blandit quis. Etiam blandit fringilla faucibus. - Nullam odio velit, consequat sed ex a, varius hendrerit ligula. - Nulla aliquam, ipsum vitae imperdiet accumsan, ex ex sollicitudin - eros, in vulputate mauris sapien sit amet lectus. Pellentesque - habitant morbi tristique senectus et netus et malesuada fames ac - turpis egestas. Praesent posuere ultrices imperdiet. -
-
+
+ + + Next.js logo + + + + +
    +
  1. + Get started by editing{' '} + + src/app/page.tsx + + . +
  2. +
  3. Save and see your changes instantly.
  4. +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tempor + quam id ante mattis tristique. Donec eget pretium mauris, et efficitur + turpis. Donec faucibus ex urna, id sagittis massa luctus id. Nam at est + ac turpis tincidunt maximus. Aenean porta ex vitae diam viverra + molestie. Aliquam ac mollis nibh. Suspendisse at mauris dapibus, + volutpat justo et, rhoncus nibh. Mauris laoreet tempor velit, eu + bibendum orci sodales et. Nam lacinia pulvinar euismod. Ut nulla felis, + interdum vel arcu eget, blandit suscipit nulla. Proin non eleifend + felis. Nunc in magna ex. Etiam quam neque, lacinia vel augue eu, + consectetur hendrerit massa. Nam rutrum erat augue, a aliquam mi + vulputate nec. Quisque non erat laoreet, ultrices nibh quis, dictum + metus. Vivamus luctus lobortis metus, nec finibus odio laoreet quis. + Donec vel porttitor velit, sit amet pellentesque leo. Fusce egestas + iaculis quam, at blandit tellus molestie nec. In sit amet aliquam nisi. + Cras in lacus nec dui blandit semper in a diam. Integer vel elit + convallis, interdum eros sed, condimentum turpis. Nunc mauris sapien, + porta ac sapien eget, consequat sollicitudin urna. Maecenas accumsan + sagittis nibh nec venenatis. Praesent convallis lectus consequat + vestibulum blandit. Sed scelerisque quam a egestas commodo. Fusce + vulputate arcu nunc, quis scelerisque quam viverra faucibus. Ut aliquam + dignissim metus eu sollicitudin. Morbi turpis nibh, tempus eget libero + eu, lobortis efficitur lacus. Praesent tempor pellentesque diam vitae + molestie. Morbi quis volutpat quam, sed placerat tortor. Vestibulum + efficitur quam vel sem lacinia placerat. Duis eu nisl pellentesque, + auctor mauris quis, porttitor nunc. Nam vehicula consectetur libero, + quis volutpat felis luctus non. Maecenas id sagittis lectus. Sed + dignissim nisl nunc, vel finibus libero accumsan a. Sed tempus, tortor + non ullamcorper sodales, ipsum lorem imperdiet lacus, gravida finibus + dui libero non lectus. Cras ex odio, feugiat vel pharetra feugiat, + rutrum nec ante. Maecenas elit arcu, ultrices non semper ut, rutrum ut + nisi. Vivamus a sem nec lorem viverra dignissim. Aliquam ac mauris eget + odio convallis viverra vulputate bibendum arcu. Nunc vel diam ac ipsum + aliquet interdum. Donec nisi metus, facilisis vitae arcu id, tempor + aliquet libero. Morbi iaculis mi urna. Aenean dui risus, rutrum at + luctus eget, ultrices in enim. Donec maximus dictum aliquet. Vivamus non + velit odio. Ut odio mauris, rhoncus a turpis at, viverra fringilla + tortor. Vivamus pellentesque, orci vitae fringilla gravida, eros justo + pharetra diam, et aliquam neque felis in nibh. Sed finibus mattis magna, + vitae molestie est scelerisque eget. Praesent aliquam vehicula ipsum id + finibus. Aenean lorem augue, dapibus ac diam sed, semper sagittis ex. + Proin congue diam in elementum condimentum. Praesent et imperdiet + mauris, quis consequat est. Nunc eros velit, posuere quis est vitae, + luctus pellentesque quam. Interdum et malesuada fames ac ante ipsum + primis in faucibus. Vivamus porttitor neque ipsum, vel dictum nulla + viverra nec. Nam in faucibus ligula. Maecenas erat purus, feugiat vel + enim vel, scelerisque feugiat erat. Vivamus justo sem, efficitur eu + hendrerit placerat, faucibus sed libero. Pellentesque euismod arcu vitae + quam eleifend tincidunt. Vestibulum vehicula nisi ut leo pellentesque + pretium. In pellentesque nisi nisi. Quisque mauris turpis, vehicula a + est et, mollis ultricies ligula. Donec quam sapien, tincidunt quis est + vitae, finibus rhoncus orci. Sed vehicula erat id accumsan malesuada. + Aliquam mollis euismod sem, a malesuada sem ultricies et. Ut scelerisque + gravida porta. Phasellus et porta ipsum, ut ultricies nisi. Ut mattis + tellus id justo pellentesque, sed rhoncus dui feugiat. Sed quis tortor a + arcu varius dapibus ac vitae odio. Vivamus pellentesque ipsum at justo + tempor, scelerisque interdum neque mattis. Nam pellentesque rhoncus + justo in rutrum. Nunc varius vel lacus at pellentesque. Mauris vel porta + arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Suspendisse pretium mi mollis laoreet iaculis. Donec tincidunt purus vel + blandit mattis. Vestibulum sodales consectetur mauris, ac malesuada enim + ultricies id. Mauris mollis sed est eu ultrices. Donec ante dolor, + fringilla vitae leo non, lacinia euismod libero. Donec risus sapien, + sodales tempus lectus ut, dignissim molestie arcu. Fusce lacinia a risus + eget tincidunt. Nunc auctor dignissim ultricies. Nam euismod sem in + luctus convallis. Mauris congue est id blandit consequat. Donec lobortis + dignissim risus a sagittis. Integer varius ultricies orci ut vulputate. + Etiam aliquet consectetur convallis. Nulla tempus mi sed sagittis + dapibus. In nisl mi, aliquet non facilisis at, gravida ut dui. Nam ac + massa ultricies, sodales lacus sit amet, finibus elit. Aenean at nibh + non nisl ullamcorper tincidunt eu nec arcu. Mauris non congue est, at + varius enim. Quisque et massa eleifend, vulputate velit vitae, imperdiet + arcu. Morbi ut libero dapibus, lacinia risus in, lobortis urna. Sed quis + neque eros. Pellentesque habitant morbi tristique senectus et netus et + malesuada fames ac turpis egestas. Mauris scelerisque sodales lacus ac + posuere. Quisque sed imperdiet est. Praesent condimentum quam ac semper + egestas. Integer faucibus erat feugiat erat pulvinar, varius molestie + turpis vestibulum. Nam rutrum finibus diam, et scelerisque enim vehicula + nec. Ut lacinia risus a ipsum blandit aliquet. Sed sit amet justo + bibendum, vestibulum nisl vitae, commodo eros. Etiam nec ipsum ante. + Nullam lacinia lobortis arcu, at scelerisque arcu. Orci varius natoque + penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec + ultrices gravida sodales. Duis vestibulum elit non consectetur + ultricies. Mauris pharetra vestibulum ipsum efficitur scelerisque. + Aenean convallis gravida ex, eu interdum sem scelerisque quis. In + commodo nisi enim, id posuere sem luctus eu. Donec tempus tristique sem. + Aenean et erat leo. Etiam sapien risus, pharetra eu tempus vel, + vulputate eu massa. Nullam fringilla nibh nulla. Nulla tristique felis + purus, in placerat dolor varius at. Etiam sed purus aliquam, tristique + sem vitae, finibus diam. Vivamus quis turpis imperdiet, viverra velit + eget, mollis enim. Aliquam sit amet mollis nunc. Phasellus eu nisi eu mi + commodo porttitor. Vivamus tellus dolor, porttitor a leo vitae, bibendum + bibendum eros. Pellentesque sagittis varius nisi, non imperdiet felis. + Aliquam orci quam, vestibulum quis diam sed, molestie semper ante. Nulla + facilisi. Cras ac libero lacus. Orci varius natoque penatibus et magnis + dis parturient montes, nascetur ridiculus mus. Sed fermentum, massa nec + finibus venenatis, risus mi molestie justo, pellentesque eleifend velit + dui faucibus elit. Sed lacinia nisi sed mi venenatis egestas. Mauris + vulputate eleifend scelerisque. Donec vitae nisi in sem congue maximus. + Nam vulputate aliquet malesuada. Fusce dolor neque, cursus laoreet mi + eu, ullamcorper scelerisque leo. Proin eu nibh ipsum. Fusce pharetra + quis tellus sit amet ornare. Curabitur luctus semper augue nec ornare. + Cras suscipit non augue ac bibendum. Quisque sed arcu enim. Sed in + mollis nisi. Quisque at mattis felis. Nunc dapibus a orci a semper. + Proin venenatis nec odio at bibendum. Cras feugiat diam ac justo + porttitor, ac molestie nibh gravida. Donec molestie commodo mi, sed + porttitor erat lacinia vitae. Vestibulum placerat venenatis dignissim. + Maecenas mollis neque enim, a congue magna commodo sed. Morbi tincidunt + sapien ac egestas accumsan. Quisque sit amet eros tortor. Donec ac purus + massa. Quisque sodales aliquet ligula, ac tempus purus mollis in. Donec + id hendrerit tortor. Fusce eget turpis at nisl porttitor dictum. Quisque + aliquam dapibus justo, id porta nunc fringilla id. Nullam id tristique + nunc. Praesent vehicula odio metus, non congue nunc varius quis. Vivamus + euismod scelerisque dui id tempus. Curabitur luctus, nisi in + pellentesque dictum, nunc ex elementum orci, vitae fermentum urna libero + congue libero. Nunc lacinia porttitor odio, id pharetra urna vulputate + in. Aenean suscipit at nunc in sagittis. Donec bibendum lorem in + pellentesque dapibus. Vestibulum et nibh et risus pellentesque viverra + ac vitae augue. Donec nec accumsan nulla, et faucibus purus. Donec quis + dapibus erat. Suspendisse sapien libero, ultricies vel lacinia vel, + interdum at ante. Nam molestie convallis malesuada. Donec mattis + faucibus est ac facilisis. Vestibulum venenatis justo at diam luctus + maximus. Praesent molestie ullamcorper odio. Nulla suscipit ligula nisl. + Suspendisse imperdiet finibus urna, sit amet iaculis felis faucibus ac. + Curabitur ut erat sed ipsum hendrerit aliquam eu et felis. Fusce + malesuada mi a ante interdum semper. Curabitur pretium elementum magna, + eu maximus diam condimentum vitae. Morbi vehicula a diam id volutpat. Ut + eu bibendum lacus, in feugiat neque. Nullam luctus nisi vitae tempus + sagittis. Nunc nec turpis vestibulum, consequat nulla in, eleifend + tellus. Etiam tristique risus urna, ac rhoncus turpis sollicitudin at. + Curabitur accumsan sapien non felis dictum, eu euismod metus volutpat. + Aenean sollicitudin nibh tincidunt dui porta viverra. Proin id odio ut + felis volutpat luctus eget eu sapien. Orci varius natoque penatibus et + magnis dis parturient montes, nascetur ridiculus mus. Phasellus iaculis + euismod metus sagittis laoreet. Vestibulum ante ipsum primis in faucibus + orci luctus et ultrices posuere cubilia curae; Proin sed dictum nisl. + Mauris in dapibus eros. Phasellus tristique sodales libero at malesuada. + Nunc vel tortor vel sapien tincidunt tristique sit amet vitae nunc. + Praesent porttitor ex a tortor finibus vehicula. Donec congue malesuada + elit, facilisis ultrices nunc pellentesque at. Suspendisse iaculis et + lacus vel volutpat. Etiam id neque ac turpis porttitor finibus. + Curabitur sed malesuada felis. Nullam vel tellus a massa eleifend + euismod. Proin tristique efficitur massa, at egestas mauris semper vel. + Sed commodo consectetur erat ac iaculis. Proin facilisis gravida + facilisis. In condimentum augue lectus, nec ultricies ipsum egestas sit + amet. Curabitur at gravida nulla, ac mollis sapien. Mauris rutrum, sem + nec sollicitudin tincidunt, lacus magna tristique nisl, vel faucibus + felis nisl vitae justo. Nam congue pretium tincidunt. Praesent pharetra, + enim sit amet mollis blandit, diam tellus interdum tellus, at mattis + erat ipsum a erat. Cras finibus fringilla turpis, eget facilisis odio + placerat vel. Cras tincidunt sed enim at laoreet. Duis vel blandit orci. + Quisque congue tincidunt ligula quis tempor. Fusce ante nunc, dictum at + suscipit vel, lacinia ut est. Morbi sagittis, mi a convallis faucibus, + ante libero dictum ante, placerat pulvinar eros massa sed felis. + Suspendisse facilisis luctus posuere. Curabitur sed sagittis urna. + Suspendisse vel feugiat orci, ut mollis dui. Maecenas efficitur, ante + tristique blandit cursus, neque ligula mollis nisl, in gravida nunc + libero id tortor. Pellentesque sit amet rutrum diam, eget pulvinar mi. + Morbi dolor magna, rutrum at quam quis, pretium consectetur nisi. Class + aptent taciti sociosqu ad litora torquent per conubia nostra, per + inceptos himenaeos. Fusce varius enim quis nibh sodales, ac semper velit + volutpat. Phasellus a eros vitae quam dignissim lacinia. Praesent tellus + ante, hendrerit auctor ornare id, accumsan id nulla. Nam vitae elit quis + purus porttitor mattis et et orci. Suspendisse magna est, ullamcorper + quis mollis ac, dapibus eget mauris. Vestibulum diam arcu, aliquam eget + mauris eu, consectetur hendrerit risus. Ut congue sem ante, eu + vestibulum nibh luctus in. Proin aliquet justo mi, ut tincidunt tellus + scelerisque et. Duis maximus orci nec elit maximus consequat. Mauris at + consectetur mi. Phasellus convallis leo non ultricies tempus. Nam id + metus placerat purus vulputate feugiat. Aenean mattis sem tempus massa + viverra consequat. Class aptent taciti sociosqu ad litora torquent per + conubia nostra, per inceptos himenaeos. Integer a est tristique, + sagittis justo ut, bibendum nunc. Morbi ullamcorper metus mauris, eu + vehicula mauris pellentesque quis. Vivamus bibendum sapien vitae quam + pulvinar, nec eleifend metus faucibus. Aliquam sed dui vitae nulla + euismod ullamcorper. Mauris accumsan volutpat orci in ultrices. Aenean + sit amet urna quis erat efficitur malesuada. Suspendisse ac quam + aliquet, venenatis eros ut, mollis elit. Nunc aliquam pharetra nisl ut + sodales. Cras imperdiet fermentum mauris at maximus. Nunc at libero ac + massa volutpat viverra ac at mauris. Fusce ut consequat est, sit amet + placerat est. Etiam tincidunt at neque id porta. In hac habitasse platea + dictumst. Vestibulum maximus mollis nisl, vitae pulvinar lacus suscipit + a. Nulla finibus ut mauris vitae sollicitudin. In in consectetur diam, + sed faucibus justo. Proin quis libero et neque luctus eleifend. Aliquam + volutpat maximus nulla, at accumsan risus molestie at. Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Donec id interdum eros. + Pellentesque ut massa id libero euismod tempus ut nec risus. + Pellentesque rutrum lorem vitae neque tempus ultricies. Nunc tincidunt + sagittis volutpat. Aliquam erat volutpat. Aliquam erat volutpat. Quisque + suscipit odio neque, volutpat blandit diam convallis ac. Maecenas + aliquam nec dui eleifend accumsan. Suspendisse interdum dolor + scelerisque nulla porttitor, eu aliquet magna efficitur. Integer massa + massa, volutpat ac odio a, eleifend accumsan velit. Sed vitae viverra + sapien, nec mollis ex. Vestibulum vel mauris ornare, tristique magna at, + pharetra velit. Morbi hendrerit eros in gravida volutpat. Curabitur a + dignissim eros, in volutpat diam. Integer vel velit magna. Etiam iaculis + ut nibh vitae vulputate. Cras pellentesque magna lorem, in placerat + risus pharetra ut. Phasellus molestie arcu non augue vehicula tristique. + Morbi dignissim arcu risus, et tempor nulla cursus quis. Morbi dignissim + tincidunt congue. Maecenas non suscipit metus. Etiam purus libero, + sagittis id fringilla nec, pharetra quis est. Nunc placerat a lectus + quis fermentum. Nullam bibendum ultricies diam, vitae interdum magna + gravida ac. Duis malesuada sagittis justo at ullamcorper. Aenean eros + nunc, ornare ac libero quis, laoreet accumsan mi. Sed blandit ut dolor + vitae faucibus. Donec quis ante non tellus vehicula iaculis. Suspendisse + vulputate eu orci in ullamcorper. Ut gravida augue odio, nec fermentum + eros tempus nec. Vivamus mattis lorem in lorem euismod, at vehicula + ligula dictum. Mauris ornare, ligula quis convallis pulvinar, lacus + mauris rutrum nulla, in facilisis erat tortor ut magna. Quisque dapibus + consequat tellus, at tincidunt metus finibus in. Nulla facilisi. + Suspendisse quis blandit magna, vel placerat ex. Integer ac nunc ut + tellus commodo facilisis ac vel ante. Morbi vitae felis pretium, mollis + ex at, rutrum erat. Sed justo ex, mollis sit amet dignissim in, pharetra + in lectus. Praesent porta eleifend dolor. Donec eget velit est. Ut et + sollicitudin mi. Donec vitae ipsum est. Curabitur in felis varius, + lobortis mauris in, dictum eros. Integer nec ante vel elit gravida + congue auctor in nulla. Nullam quis sapien ut libero ultrices aliquam. + Fusce in tellus et tortor bibendum feugiat. Etiam non gravida neque. + Quisque ac nibh tincidunt, varius augue in, faucibus eros. Praesent non + tempus arcu, ac commodo elit. Nulla tempor semper elit, quis tristique + justo aliquam sit amet. Praesent eleifend ante eu nunc convallis, id + posuere ligula consequat. Nulla luctus tincidunt leo. Nam porta ac + ligula eget scelerisque. Maecenas dapibus porttitor velit. Vestibulum + volutpat eu felis et volutpat. Proin iaculis id arcu faucibus auctor. + Quisque a ultrices elit. Pellentesque sit amet tempus mauris. Morbi sem + leo, cursus sed mollis sit amet, maximus a neque. Morbi eleifend eu enim + in facilisis. Praesent eu tortor a turpis vestibulum accumsan quis ut + justo. Etiam et tempor nibh. Pellentesque blandit facilisis neque auctor + faucibus. Maecenas consectetur eget risus a fermentum. Ut sed + scelerisque quam. Aenean interdum vel dolor quis ullamcorper. Etiam sed + lectus porttitor, feugiat libero at, venenatis mauris. Vivamus ut sapien + venenatis nibh rhoncus feugiat et et orci. Duis vitae efficitur risus. + Proin quis orci dignissim, tincidunt lacus ac, maximus diam. Cras + tempor, leo sed consectetur volutpat, velit tortor malesuada nunc, sit + amet placerat felis velit id justo. Curabitur varius nisl ut elit + elementum sodales. Quisque volutpat dui vitae elit euismod, et sodales + mi pretium. Morbi sed nisl dui. In hac habitasse platea dictumst. Morbi + et tortor convallis, lacinia lorem vitae, lacinia mauris. Integer + convallis ex nisi, quis hendrerit ipsum blandit vitae. Quisque ut velit + arcu. Proin enim leo, mollis vitae erat scelerisque, rhoncus tempor + libero. In hac habitasse platea dictumst. Sed quis purus ac orci dictum + accumsan vel consectetur ex. In gravida, justo in pharetra consequat, + mauris quam facilisis massa, vel egestas magna ex sed eros. Mauris ante + elit, auctor non urna vel, pharetra accumsan dui. Nam mollis dolor id + sem euismod, tincidunt posuere tellus malesuada. Morbi vel porta est. + Sed non enim a justo venenatis faucibus eu sit amet mauris. Aenean quis + euismod ipsum. Fusce sit amet pharetra tellus. Suspendisse eleifend + tristique mollis. Etiam non urna quis ligula pellentesque sollicitudin. + Suspendisse sit amet cursus libero. Vivamus sed sagittis lacus. Sed + dignissim ullamcorper magna eget feugiat. Aenean vel purus sodales dui + consequat imperdiet sit amet sed ante. Praesent urna velit, vestibulum + sed magna eu, tincidunt tincidunt justo. Duis ac bibendum lectus, vel + accumsan nisl. Proin gravida massa ut pharetra ultricies. Aliquam quis + gravida mauris, sed egestas est. In at neque nisi. Morbi fringilla + accumsan ex, eu finibus velit ultrices eget. Sed tincidunt, tortor a + sagittis pharetra, leo dui tincidunt felis, eu porta arcu felis eget + lacus. Aliquam sollicitudin consequat commodo. Nam risus massa, + tristique vitae aliquam a, ullamcorper eget urna. Proin sit amet tempus + mauris. Morbi ultricies ullamcorper leo, ac blandit sapien ornare non. + Vestibulum et mi et velit ultricies vulputate. Sed aliquam sagittis mi + ut vestibulum. Etiam dictum finibus feugiat. Aenean et laoreet felis, a + porta purus. Donec pulvinar elit vitae scelerisque suscipit. Morbi at + imperdiet sem. Nam non metus quis odio gravida porta. Nam sit amet + sodales lacus. Nulla facilisi. Cras auctor lectus a massa tempus + pulvinar. Sed urna ante, tempus ut dolor sed, sagittis suscipit odio. + Nulla in venenatis nibh. Nulla tempor, dolor ultricies interdum lacinia, + nisl justo suscipit velit, eget condimentum tellus magna sit amet dui. + Cras nec vestibulum metus, sed blandit nibh. Donec ac tempor ligula, + pharetra semper tellus. In convallis arcu quis dui euismod, bibendum + lobortis leo consequat. Morbi tincidunt lobortis mauris, et cursus + sapien faucibus sit amet. Lorem ipsum dolor sit amet, consectetur + adipiscing elit. Pellentesque varius pellentesque egestas. Donec in + ultrices lectus, at lobortis dolor. Nunc tincidunt in nunc quis semper. + Ut interdum sollicitudin neque id gravida. Ut quis ipsum quis nisi + semper fermentum ac et orci. Etiam sollicitudin, magna non tincidunt + eleifend, sem ante sodales massa, at placerat nunc libero vel ipsum. + Vivamus a ex nec arcu tempus laoreet. Curabitur dictum ligula sed leo + euismod volutpat. Vestibulum ut interdum augue. Nunc in pulvinar justo, + vitae placerat justo. Sed ultrices luctus ligula, sit amet tempor felis + tempus sit amet. Sed feugiat ligula id nulla congue, at sollicitudin + mauris rhoncus. Ut ullamcorper semper felis non finibus. Etiam venenatis + risus ac augue eleifend, at venenatis ex blandit. Ut ullamcorper quam + magna, et pulvinar leo volutpat non. Integer nec tellus lectus. + Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere + cubilia curae; Integer interdum purus sagittis, sollicitudin dui eget, + cursus nisi. Nulla pellentesque vestibulum massa, et vehicula ipsum + rhoncus ut. Mauris at quam ac augue commodo pretium non vel ligula. + Aliquam erat volutpat. Suspendisse lobortis ligula ac bibendum dapibus. + Quisque feugiat condimentum elit, vitae fermentum ligula sagittis vitae. + In porttitor condimentum nunc, nec fringilla libero ultricies sed. + Mauris nulla massa, finibus nec nisi vitae, egestas congue felis. Sed + hendrerit justo vel justo pretium fermentum. Nulla dictum risus ut + scelerisque blandit. Quisque dictum pretium ullamcorper. Aliquam dictum + pretium dui nec blandit. Sed vitae nunc dui. Integer pharetra id sem eu + rutrum. Suspendisse in sagittis lorem. Phasellus eget urna laoreet, + sollicitudin metus id, mollis dolor. Duis semper pulvinar felis, + consectetur vulputate orci pharetra a. Aliquam non aliquet ipsum. Morbi + nec neque et ex pellentesque porttitor vel quis libero. Vivamus nisl + ligula, laoreet id sollicitudin in, eleifend vel tortor. Proin aliquet, + tellus volutpat lobortis varius, tortor sem porta leo, ut imperdiet + ligula quam sed nibh. Duis at augue mollis, ultricies nunc sit amet, + volutpat felis. Ut a rhoncus mi. In ultricies ipsum vitae mi faucibus, + sit amet elementum lorem iaculis. Suspendisse ut nibh lorem. Orci varius + natoque penatibus et magnis dis parturient montes, nascetur ridiculus + mus. Nulla ultrices eu ex at aliquam. Mauris pretium ligula quis nisl + eleifend cursus. Quisque porttitor vestibulum dui, a sollicitudin dolor + porttitor id. Aenean molestie efficitur tellus a aliquam. Vivamus + posuere quam nec dui porta sagittis. Maecenas sed consequat ante. + Suspendisse gravida nisl pharetra turpis luctus sodales. Nullam + condimentum quam eget nulla scelerisque, at malesuada libero pulvinar. + Nulla malesuada augue eget sem pretium ullamcorper. Suspendisse quis + erat quis sem consequat volutpat. Quisque non eleifend ante, ac maximus + neque. Nulla id auctor massa, semper fermentum nisl. Aliquam odio metus, + convallis et sodales in, elementum vel nisi. Nunc volutpat erat commodo + augue euismod, placerat aliquam dolor aliquet. Duis tincidunt lacinia + vehicula. Aliquam erat volutpat. Vivamus consequat bibendum fringilla. + Maecenas eget nisl vitae nisl hendrerit venenatis id ac metus. + Vestibulum consectetur vitae sem eget sollicitudin. Integer a ultricies + mi, id euismod urna. Quisque in metus ac lectus tincidunt varius vel eu + quam. Cras non vehicula nulla. Orci varius natoque penatibus et magnis + dis parturient montes, nascetur ridiculus mus. Suspendisse maximus + mauris ut dolor tincidunt, id molestie lacus accumsan. Maecenas turpis + libero, congue a tellus ut, fermentum ultricies diam. Praesent congue + nulla id vestibulum molestie. Suspendisse vitae magna ac dolor lacinia + finibus. Nullam lobortis commodo ante, ac rutrum metus cursus quis. Orci + varius natoque penatibus et magnis dis parturient montes, nascetur + ridiculus mus. Cras finibus faucibus nisi vel mattis. In hac habitasse + platea dictumst. Phasellus aliquam viverra felis, sit amet laoreet leo + fringilla et. Sed sed condimentum augue. Ut in orci magna. Nunc + condimentum erat nec purus porttitor suscipit. Nulla sed risus + sollicitudin, sagittis justo vel, pellentesque neque. Curabitur in felis + rhoncus, feugiat arcu in, aliquam urna. Vivamus dapibus est felis, nec + feugiat purus scelerisque a. Praesent sed eros at sem ornare luctus. + Donec rhoncus semper lacinia. Etiam in placerat leo, vel bibendum massa. + Pellentesque tempus neque sem, et facilisis ligula pharetra nec. + Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere + cubilia curae; Donec at interdum odio, et consectetur nisi. Morbi + blandit volutpat enim nec gravida. Nam lacinia dui sed dolor luctus + scelerisque. Curabitur consectetur tincidunt cursus. Quisque felis + dolor, volutpat sit amet luctus vel, volutpat sed ante. Morbi nulla + tellus, luctus non semper id, dignissim ut nisl. Fusce urna ligula, + blandit ut vehicula sed, malesuada non risus. Proin ac massa bibendum, + pretium velit at, tristique orci. Phasellus accumsan enim eget urna + congue, id auctor massa sollicitudin. Ut quis nisi sed metus placerat + aliquam sed ac sem. Integer lobortis justo lectus, vitae posuere est + tristique eget. Morbi a gravida urna. Nullam a sem a urna fermentum + semper eu quis dui. Vestibulum iaculis, ligula vitae vehicula pulvinar, + nisi ante tempor risus, eleifend vehicula quam quam eget nisi. Morbi + varius blandit varius. In lacinia neque at ante elementum, vel hendrerit + magna fringilla. Nam scelerisque nisi at sodales varius. Class aptent + taciti sociosqu ad litora torquent per conubia nostra, per inceptos + himenaeos. Nulla rhoncus arcu vitae sem elementum ultrices. In ut + placerat lorem. Praesent ut turpis orci. Duis in egestas diam, vel + efficitur turpis. Maecenas quam turpis, convallis et eleifend non, + venenatis ut tortor. Quisque vitae turpis tempor, elementum orci eu, + cursus diam. Vestibulum at sagittis nisi, eu euismod libero. Integer eu + velit commodo, gravida mi eu, rhoncus turpis. Morbi et nulla a lacus + lobortis scelerisque. Etiam rutrum lacus nec aliquet ornare. Morbi odio + dolor, pulvinar sit amet odio sit amet, venenatis porttitor neque. Nam + et laoreet elit. Suspendisse vehicula velit quis dolor rhoncus, nec + posuere tellus sollicitudin. Aliquam erat volutpat. Sed vel tempor eros. + Morbi pulvinar ante et metus interdum eleifend. Lorem ipsum dolor sit + amet, consectetur adipiscing elit. Nullam nec ex ipsum. In id cursus + purus, nec pharetra lorem. Vestibulum enim urna, pretium in pharetra + vitae, maximus in felis. Praesent placerat euismod dolor vitae pretium. + Pellentesque habitant morbi tristique senectus et netus et malesuada + fames ac turpis egestas. Nulla quis laoreet lorem. Duis est ipsum, + tempus in nunc cursus, rutrum malesuada sapien. Nullam condimentum, + ligula non ultricies gravida, risus magna vehicula risus, non iaculis + nunc tortor ac elit. Ut consequat, velit in luctus fringilla, urna orci + efficitur diam, sed posuere urna eros ac nunc. Nunc vel enim augue. + Phasellus placerat tortor et porta molestie. Curabitur vel arcu vitae + orci congue efficitur. Integer fermentum porttitor justo, in tristique + dolor suscipit eleifend. Nullam elementum posuere magna, vel consequat + dolor pellentesque ut. Vivamus congue lectus id arcu egestas, ac + lobortis quam sollicitudin. Nulla tempus molestie justo, et vehicula + nulla imperdiet elementum. Mauris rhoncus velit augue, vitae tincidunt + ligula elementum a. Integer tristique at lectus id ultricies. Morbi a + neque euismod tortor posuere mollis a quis nibh. Vivamus vitae gravida + metus, at tincidunt nunc. Vestibulum felis ante, ultrices eget ornare + vel, molestie sit amet mi. Nunc venenatis elementum sagittis. Fusce + venenatis dui ut risus porttitor, molestie iaculis nulla scelerisque. + Phasellus eu posuere felis, commodo aliquet est. Vestibulum id est nec + felis sollicitudin lobortis. Phasellus ac condimentum ligula. Cras sed + rutrum lacus, in cursus nibh. Duis eu pulvinar felis. In finibus nulla + in interdum venenatis. Quisque sed felis suscipit, rhoncus dui non, + condimentum sem. Nam pulvinar dolor mollis tempus convallis. Vestibulum + vulputate condimentum viverra. Praesent pulvinar lacus sodales, + convallis lacus in, consequat velit. Ut pulvinar neque ante, at + vestibulum ante posuere id. Donec rhoncus ante at varius iaculis. Aenean + molestie eros et pulvinar consectetur. Nam convallis laoreet accumsan. + Nunc vel laoreet erat. Vivamus tristique turpis elit, non aliquam felis + malesuada sed. In eu scelerisque odio, a porttitor nulla. Pellentesque + at mauris a enim feugiat dapibus vel id dolor. In hac habitasse platea + dictumst. Morbi eget diam pretium, commodo tellus at, finibus turpis. + Donec in mauris lobortis, interdum mi vel, pharetra lectus. Phasellus + justo felis, fringilla nec lacus ac, facilisis tempor mi. Donec + fringilla risus arcu, quis eleifend leo condimentum in. Aliquam + sollicitudin cursus neque id facilisis. Nunc condimentum eros nec mi + imperdiet faucibus. Nullam luctus leo a faucibus dictum. Aenean sit amet + maximus sem. Integer in nisl finibus, accumsan turpis sed, interdum dui. + Sed pulvinar vulputate justo ut dictum. Morbi bibendum at odio non + egestas. Fusce bibendum ante vel leo convallis malesuada. Aenean + vestibulum tellus id pulvinar mattis. Pellentesque non ante bibendum, + vulputate nisl et, condimentum dui. Nam condimentum vulputate sapien, + non mattis leo lacinia at. Duis et blandit diam. In commodo orci dolor. + Fusce vehicula consectetur ante tincidunt placerat. Nulla volutpat ante + et nulla faucibus, at interdum elit viverra. Aliquam tincidunt nulla + eros, at dapibus sapien porta non. Nunc congue tempor leo. Praesent + euismod efficitur ipsum, a sollicitudin arcu dictum sed. Sed + pellentesque condimentum nunc, non fermentum orci ultrices vitae. + Phasellus sodales ultrices auctor. Duis sed nunc quis dui tincidunt + tincidunt. Proin quis viverra nisl. Vestibulum luctus, nulla elementum + porta congue, ipsum dolor interdum ligula, nec hendrerit ipsum libero + sit amet massa. Donec vel dignissim orci. Ut finibus nisi vitae aliquet + ornare. Integer pharetra nunc id magna viverra aliquet. Mauris consequat + turpis eros, tempor sagittis tellus egestas eget. Aliquam condimentum + lectus ut aliquam vestibulum. Phasellus eget tellus ut diam convallis + iaculis eu ut mauris. Cras dignissim convallis metus, et imperdiet diam + dignissim eget. Vivamus mattis nisi eget orci suscipit volutpat. + Maecenas fermentum molestie purus in scelerisque. Etiam at mi quis metus + blandit condimentum. Suspendisse quis molestie augue, ut bibendum + tellus. Fusce nec varius ligula, in sagittis nunc. In eget tortor vel + massa varius feugiat in a lacus. Ut feugiat tortor nibh, nec condimentum + velit cursus vel. Suspendisse non leo pretium, vestibulum dolor vitae, + dictum sem. Phasellus ut augue eu orci sodales venenatis et eu tortor. + Quisque a nunc quis tellus consectetur vestibulum. Donec vitae elit + orci. Ut volutpat vehicula diam, eget suscipit lorem tristique + fermentum. In laoreet at magna sed tincidunt. Nullam a lectus ut quam + faucibus tincidunt vitae at ante. Fusce fringilla ut felis nec ultrices. + Maecenas varius vestibulum quam, quis aliquam urna dictum at. Sed varius + lorem a metus molestie sagittis. In hac habitasse platea dictumst. + Curabitur vel orci orci. Donec lobortis massa nulla, quis fermentum + metus blandit quis. Etiam blandit fringilla faucibus. Nullam odio velit, + consequat sed ex a, varius hendrerit ligula. Nulla aliquam, ipsum vitae + imperdiet accumsan, ex ex sollicitudin eros, in vulputate mauris sapien + sit amet lectus. Pellentesque habitant morbi tristique senectus et netus + et malesuada fames ac turpis egestas. Praesent posuere ultrices + imperdiet.
- +
) } diff --git a/src/components/theme-provider.tsx b/src/components/theme-provider.tsx index 88226e8..5dd57a5 100644 --- a/src/components/theme-provider.tsx +++ b/src/components/theme-provider.tsx @@ -12,7 +12,10 @@ export function ThemeProvider({ [key: string]: unknown }) { return ( - + {children} ) diff --git a/src/components/ui/NewsletterForm.tsx b/src/components/ui/NewsletterForm.tsx new file mode 100644 index 0000000..9772a7f --- /dev/null +++ b/src/components/ui/NewsletterForm.tsx @@ -0,0 +1,63 @@ +'use client' +import confetti from 'canvas-confetti' +import { Button } from './button' +import { Input } from './input' + +const NewsletterForm = () => { + const handleClick = () => { + const end = Date.now() + 3 * 1000 // 3 seconds + const colors = ['#a786ff', '#fd8bbc', '#eca184', '#f8deb1'] + + const frame = () => { + if (Date.now() > end) return + + confetti({ + particleCount: 2, + angle: 60, + spread: 55, + startVelocity: 60, + origin: { x: 0, y: 0.5 }, + colors: colors, + }) + confetti({ + particleCount: 2, + angle: 120, + spread: 55, + startVelocity: 60, + origin: { x: 1, y: 0.5 }, + colors: colors, + }) + + requestAnimationFrame(frame) + } + + frame() + } + + return ( +
+
+ +
+
+
+ +
+
+
+ ) +} + +export default NewsletterForm diff --git a/src/components/ui/border-beam.tsx b/src/components/ui/border-beam.tsx new file mode 100644 index 0000000..a720307 --- /dev/null +++ b/src/components/ui/border-beam.tsx @@ -0,0 +1,49 @@ +import { cn } from "@/lib/utils"; + +interface BorderBeamProps { + className?: string; + size?: number; + duration?: number; + borderWidth?: number; + anchor?: number; + colorFrom?: string; + colorTo?: string; + delay?: number; +} + +export const BorderBeam = ({ + className, + size = 200, + duration = 15, + anchor = 90, + borderWidth = 1.5, + colorFrom = "#ffaa40", + colorTo = "#9c40ff", + delay = 0, +}: BorderBeamProps) => { + return ( +
+ ); +}; diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx new file mode 100644 index 0000000..cabfbfc --- /dev/null +++ b/src/components/ui/card.tsx @@ -0,0 +1,76 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/src/components/ui/confetti.tsx b/src/components/ui/confetti.tsx new file mode 100644 index 0000000..3aa8597 --- /dev/null +++ b/src/components/ui/confetti.tsx @@ -0,0 +1,127 @@ +import type { ReactNode } from "react"; +import React, { + createContext, + forwardRef, + useCallback, + useEffect, + useImperativeHandle, + useMemo, + useRef, +} from "react"; +import type { + GlobalOptions as ConfettiGlobalOptions, + CreateTypes as ConfettiInstance, + Options as ConfettiOptions, +} from "canvas-confetti"; +import confetti from "canvas-confetti"; + +import { Button, ButtonProps } from "@/components/ui/button"; + +type Api = { + fire: (options?: ConfettiOptions) => void; +}; + +type Props = React.ComponentPropsWithRef<"canvas"> & { + options?: ConfettiOptions; + globalOptions?: ConfettiGlobalOptions; + manualstart?: boolean; + children?: ReactNode; +}; + +export type ConfettiRef = Api | null; + +const ConfettiContext = createContext({} as Api); + +const Confetti = forwardRef((props, ref) => { + const { + options, + globalOptions = { resize: true, useWorker: true }, + manualstart = false, + children, + ...rest + } = props; + const instanceRef = useRef(null); // confetti instance + + const canvasRef = useCallback( + // https://react.dev/reference/react-dom/components/common#ref-callback + // https://reactjs.org/docs/refs-and-the-dom.html#callback-refs + (node: HTMLCanvasElement) => { + if (node !== null) { + // is mounted => create the confetti instance + if (instanceRef.current) return; // if not already created + instanceRef.current = confetti.create(node, { + ...globalOptions, + resize: true, + }); + } else { + // is unmounted => reset and destroy instanceRef + if (instanceRef.current) { + instanceRef.current.reset(); + instanceRef.current = null; + } + } + }, + [globalOptions], + ); + + // `fire` is a function that calls the instance() with `opts` merged with `options` + const fire = useCallback( + (opts = {}) => instanceRef.current?.({ ...options, ...opts }), + [options], + ); + + const api = useMemo( + () => ({ + fire, + }), + [fire], + ); + + useImperativeHandle(ref, () => api, [api]); + + useEffect(() => { + if (!manualstart) { + fire(); + } + }, [manualstart, fire]); + + return ( + + + {children} + + ); +}); + +interface ConfettiButtonProps extends ButtonProps { + options?: ConfettiOptions & + ConfettiGlobalOptions & { canvas?: HTMLCanvasElement }; + children?: React.ReactNode; +} + +function ConfettiButton({ options, children, ...props }: ConfettiButtonProps) { + const handleClick = (event: React.MouseEvent) => { + const rect = event.currentTarget.getBoundingClientRect(); + const x = rect.left + rect.width / 2; + const y = rect.top + rect.height / 2; + confetti({ + ...options, + origin: { + x: x / window.innerWidth, + y: y / window.innerHeight, + }, + }); + }; + + return ( + + ); +} + +Confetti.displayName = "Confetti"; + +export { Confetti, ConfettiButton }; + +export default Confetti; diff --git a/src/components/ui/dot-pattern.tsx b/src/components/ui/dot-pattern.tsx new file mode 100644 index 0000000..ea42a5e --- /dev/null +++ b/src/components/ui/dot-pattern.tsx @@ -0,0 +1,56 @@ +import { useId } from "react"; + +import { cn } from "@/lib/utils"; + +interface DotPatternProps { + width?: any; + height?: any; + x?: any; + y?: any; + cx?: any; + cy?: any; + cr?: any; + className?: string; + [key: string]: any; +} +export function DotPattern({ + width = 16, + height = 16, + x = 0, + y = 0, + cx = 1, + cy = 1, + cr = 1, + className, + ...props +}: DotPatternProps) { + const id = useId(); + + return ( + + ); +} + +export default DotPattern; diff --git a/src/components/ui/flickering-grid.tsx b/src/components/ui/flickering-grid.tsx new file mode 100644 index 0000000..1768995 --- /dev/null +++ b/src/components/ui/flickering-grid.tsx @@ -0,0 +1,193 @@ +'use client' + +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' + +interface FlickeringGridProps { + squareSize?: number + gridGap?: number + flickerChance?: number + color?: string + width?: number + height?: number + className?: string + + maxOpacity?: number +} + +const FlickeringGrid: React.FC = ({ + squareSize = 4, + gridGap = 6, + flickerChance = 0.3, + color = 'rgb(0, 0, 0)', + width, + height, + className, + maxOpacity = 0.3, +}) => { + const canvasRef = useRef(null) + const containerRef = useRef(null) + const [isInView, setIsInView] = useState(false) + const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 }) + + const memoizedColor = useMemo(() => { + const toRGBA = (color: string) => { + if (typeof window === 'undefined') { + return `rgba(0, 0, 0,` + } + const canvas = document.createElement('canvas') + canvas.width = canvas.height = 1 + const ctx = canvas.getContext('2d') + if (!ctx) return 'rgba(255, 0, 0,' + ctx.fillStyle = color + ctx.fillRect(0, 0, 1, 1) + const [r, g, b] = Array.from(ctx.getImageData(0, 0, 1, 1).data) + return `rgba(${r}, ${g}, ${b},` + } + return toRGBA(color) + }, [color]) + + const setupCanvas = useCallback( + (canvas: HTMLCanvasElement, width: number, height: number) => { + const dpr = window.devicePixelRatio || 1 + canvas.width = width * dpr + canvas.height = height * dpr + canvas.style.width = `${width}px` + canvas.style.height = `${height}px` + const cols = Math.floor(width / (squareSize + gridGap)) + const rows = Math.floor(height / (squareSize + gridGap)) + + const squares = new Float32Array(cols * rows) + for (let i = 0; i < squares.length; i++) { + squares[i] = Math.random() * maxOpacity + } + + return { cols, rows, squares, dpr } + }, + [squareSize, gridGap, maxOpacity] + ) + + const updateSquares = useCallback( + (squares: Float32Array, deltaTime: number) => { + for (let i = 0; i < squares.length; i++) { + if (Math.random() < flickerChance * deltaTime) { + squares[i] = Math.random() * maxOpacity + } + } + }, + [flickerChance, maxOpacity] + ) + + const drawGrid = useCallback( + ( + ctx: CanvasRenderingContext2D, + width: number, + height: number, + cols: number, + rows: number, + squares: Float32Array, + dpr: number + ) => { + ctx.clearRect(0, 0, width, height) + ctx.fillStyle = 'transparent' + ctx.fillRect(0, 0, width, height) + + for (let i = 0; i < cols; i++) { + for (let j = 0; j < rows; j++) { + const opacity = squares[i * rows + j] + ctx.fillStyle = `${memoizedColor}${opacity})` + ctx.fillRect( + i * (squareSize + gridGap) * dpr, + j * (squareSize + gridGap) * dpr, + squareSize * dpr, + squareSize * dpr + ) + } + } + }, + [memoizedColor, squareSize, gridGap] + ) + + useEffect(() => { + const canvas = canvasRef.current + const container = containerRef.current + if (!canvas || !container) return + + const ctx = canvas.getContext('2d') + if (!ctx) return + + let animationFrameId: number + let gridParams: ReturnType + + const updateCanvasSize = () => { + const newWidth = width || container.clientWidth + const newHeight = height || container.clientHeight + setCanvasSize({ width: newWidth, height: newHeight }) + gridParams = setupCanvas(canvas, newWidth, newHeight) + } + + updateCanvasSize() + + let lastTime = 0 + const animate = (time: number) => { + if (!isInView) return + + const deltaTime = (time - lastTime) / 1000 + lastTime = time + + updateSquares(gridParams.squares, deltaTime) + drawGrid( + ctx, + canvas.width, + canvas.height, + gridParams.cols, + gridParams.rows, + gridParams.squares, + gridParams.dpr + ) + animationFrameId = requestAnimationFrame(animate) + } + + const resizeObserver = new ResizeObserver(() => { + updateCanvasSize() + }) + + resizeObserver.observe(container) + + const intersectionObserver = new IntersectionObserver( + ([entry]) => { + setIsInView(entry.isIntersecting) + }, + { threshold: 0 } + ) + + intersectionObserver.observe(canvas) + + if (isInView) { + animationFrameId = requestAnimationFrame(animate) + } + + return () => { + cancelAnimationFrame(animationFrameId) + resizeObserver.disconnect() + intersectionObserver.disconnect() + } + }, [setupCanvas, updateSquares, drawGrid, width, height, isInView]) + + return ( +
+ +
+ ) +} + +export default FlickeringGrid diff --git a/src/components/ui/header.tsx b/src/components/ui/header.tsx index 1d1f050..1decc3f 100644 --- a/src/components/ui/header.tsx +++ b/src/components/ui/header.tsx @@ -18,10 +18,11 @@ import { Settings, User, } from 'lucide-react' +import { useTheme } from 'next-themes' import Image from 'next/image' import Link from 'next/link' import { usePathname } from 'next/navigation' -import React from 'react' +import React, { useState } from 'react' import { Avatar, AvatarFallback, AvatarImage } from './avatar' import { Button } from './button' import { @@ -141,7 +142,8 @@ const ListItem: React.FC<{ const Header: React.FC = () => { const pathname = usePathname() - const [isOpen, setIsOpen] = React.useState(false) + const { resolvedTheme } = useTheme() + const [isOpen, setIsOpen] = useState(false) return (
@@ -189,7 +191,11 @@ const Header: React.FC = () => { className='flex items-center space-x-2 rtl:space-x-reverse' > FrontChapter { + return ( +
+
+
+ Logo +
+
+ + + +
+
+ + با جامعه‌ی فرانت‌اند ایران +
+

+ اینجا محلی صمیمی برای گفتگوی تخصصی هست. توی فرانت چیز هر دو هفته یک + بار، دور هم جمع می‌شیم و درمورد چالش‌هایی که بهشون برخوردیم گپ و گفت + می‌کنیم. +

+
+ +
+
+ +
+ ) +} + +export default HeroSection diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx new file mode 100644 index 0000000..69b64fb --- /dev/null +++ b/src/components/ui/input.tsx @@ -0,0 +1,22 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Input = React.forwardRef>( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/src/components/ui/meteors.tsx b/src/components/ui/meteors.tsx new file mode 100644 index 0000000..6af48c8 --- /dev/null +++ b/src/components/ui/meteors.tsx @@ -0,0 +1,44 @@ +"use client"; + +import { useEffect, useState } from "react"; + +import { cn } from "@/lib/utils"; + +interface MeteorsProps { + number?: number; +} +export const Meteors = ({ number = 20 }: MeteorsProps) => { + const [meteorStyles, setMeteorStyles] = useState>( + [], + ); + + useEffect(() => { + const styles = [...new Array(number)].map(() => ({ + top: -5, + left: Math.floor(Math.random() * window.innerWidth) + "px", + animationDelay: Math.random() * 1 + 0.2 + "s", + animationDuration: Math.floor(Math.random() * 8 + 2) + "s", + })); + setMeteorStyles(styles); + }, [number]); + + return ( + <> + {[...meteorStyles].map((style, idx) => ( + // Meteor Head + + {/* Meteor Tail */} +
+ + ))} + + ); +}; + +export default Meteors; diff --git a/src/components/ui/neon-gradient-card.tsx b/src/components/ui/neon-gradient-card.tsx new file mode 100644 index 0000000..3192789 --- /dev/null +++ b/src/components/ui/neon-gradient-card.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { + CSSProperties, + ReactElement, + ReactNode, + useEffect, + useRef, + useState, +} from "react"; + +import { cn } from "@/lib/utils"; + +interface NeonColorsProps { + firstColor: string; + secondColor: string; +} + +interface NeonGradientCardProps { + /** + * @default
+ * @type ReactElement + * @description + * The component to be rendered as the card + * */ + as?: ReactElement; + /** + * @default "" + * @type string + * @description + * The className of the card + */ + className?: string; + + /** + * @default "" + * @type ReactNode + * @description + * The children of the card + * */ + children?: ReactNode; + + /** + * @default 5 + * @type number + * @description + * The size of the border in pixels + * */ + borderSize?: number; + + /** + * @default 20 + * @type number + * @description + * The size of the radius in pixels + * */ + borderRadius?: number; + + /** + * @default "{ firstColor: '#ff00aa', secondColor: '#00FFF1' }" + * @type string + * @description + * The colors of the neon gradient + * */ + neonColors?: NeonColorsProps; + + [key: string]: any; +} + +const NeonGradientCard: React.FC = ({ + className, + children, + borderSize = 2, + borderRadius = 20, + neonColors = { + firstColor: "#ff00aa", + secondColor: "#00FFF1", + }, + ...props +}) => { + const containerRef = useRef(null); + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); + + useEffect(() => { + const updateDimensions = () => { + if (containerRef.current) { + const { offsetWidth, offsetHeight } = containerRef.current; + setDimensions({ width: offsetWidth, height: offsetHeight }); + } + }; + + updateDimensions(); + window.addEventListener("resize", updateDimensions); + + return () => { + window.removeEventListener("resize", updateDimensions); + }; + }, []); + + useEffect(() => { + if (containerRef.current) { + const { offsetWidth, offsetHeight } = containerRef.current; + setDimensions({ width: offsetWidth, height: offsetHeight }); + } + }, [children]); + + return ( +
+
+ {children} +
+
+ ); +}; + +export { NeonGradientCard }; diff --git a/src/components/ui/particles.tsx b/src/components/ui/particles.tsx new file mode 100644 index 0000000..da54d63 --- /dev/null +++ b/src/components/ui/particles.tsx @@ -0,0 +1,308 @@ +'use client' + +import { cn } from '@/lib/utils' +import React, { useEffect, useRef, useState } from 'react' + +interface MousePosition { + x: number + y: number +} + +function MousePosition(): MousePosition { + const [mousePosition, setMousePosition] = useState({ + x: 0, + y: 0, + }) + + useEffect(() => { + const handleMouseMove = (event: MouseEvent) => { + setMousePosition({ x: event.clientX, y: event.clientY }) + } + + window.addEventListener('mousemove', handleMouseMove) + + return () => { + window.removeEventListener('mousemove', handleMouseMove) + } + }, []) + + return mousePosition +} + +interface ParticlesProps { + className?: string + quantity?: number + staticity?: number + ease?: number + size?: number + refresh?: boolean + color?: string + vx?: number + vy?: number +} + +const Particles: React.FC = ({ + className = '', + quantity = 100, + staticity = 50, + ease = 50, + size = 0.4, + refresh = false, + color = '#ffffff', + vx = 0, + vy = 0, +}) => { + const canvasRef = useRef(null) + const canvasContainerRef = useRef(null) + const context = useRef(null) + const circles = useRef([]) + const mousePosition = MousePosition() + const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 }) + const canvasSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 }) + const dpr = typeof window !== 'undefined' ? window.devicePixelRatio : 1 + const rafID = useRef(null) + const carrotImage = useRef(null) + + useEffect(() => { + // Initialize the carrot image only in the browser + const img = new Image() + img.src = '/havij/images/logo-without-text-white.svg' // Update this path to your carrot SVG + carrotImage.current = img + }, []) + + useEffect(() => { + if (canvasRef.current) { + context.current = canvasRef.current.getContext('2d') + } + initCanvas() + animate() + window.addEventListener('resize', initCanvas) + + return () => { + if (rafID.current != null) { + window.cancelAnimationFrame(rafID.current) + } + window.removeEventListener('resize', initCanvas) + } + }, [color]) + + useEffect(() => { + if (canvasRef.current) { + context.current = canvasRef.current.getContext('2d') + } + initCanvas() + animate() + window.addEventListener('resize', initCanvas) + + return () => { + if (rafID.current != null) { + window.cancelAnimationFrame(rafID.current) + } + window.removeEventListener('resize', initCanvas) + } + }, [color]) + + useEffect(() => { + onMouseMove() + }, [mousePosition.x, mousePosition.y]) + + useEffect(() => { + initCanvas() + }, [refresh]) + + const initCanvas = () => { + resizeCanvas() + drawParticles() + } + + const onMouseMove = () => { + if (canvasRef.current) { + const rect = canvasRef.current.getBoundingClientRect() + const { w, h } = canvasSize.current + const x = mousePosition.x - rect.left - w / 2 + const y = mousePosition.y - rect.top - h / 2 + const inside = x < w / 2 && x > -w / 2 && y < h / 2 && y > -h / 2 + if (inside) { + mouse.current.x = x + mouse.current.y = y + } + } + } + + type Circle = { + x: number + y: number + translateX: number + translateY: number + size: number + alpha: number + targetAlpha: number + dx: number + dy: number + magnetism: number + } + + const resizeCanvas = () => { + if (canvasContainerRef.current && canvasRef.current && context.current) { + circles.current.length = 0 + canvasSize.current.w = canvasContainerRef.current.offsetWidth + canvasSize.current.h = canvasContainerRef.current.offsetHeight + canvasRef.current.width = canvasSize.current.w * dpr + canvasRef.current.height = canvasSize.current.h * dpr + canvasRef.current.style.width = `${canvasSize.current.w}px` + canvasRef.current.style.height = `${canvasSize.current.h}px` + context.current.scale(dpr, dpr) + } + } + + const circleParams = (): Circle => { + const x = Math.floor(Math.random() * canvasSize.current.w) + const y = Math.floor(Math.random() * canvasSize.current.h) + const translateX = 0 + const translateY = 0 + const pSize = Math.floor(Math.random() * 2) + size + const alpha = 0 + const targetAlpha = parseFloat((Math.random() * 0.6 + 0.1).toFixed(1)) + const dx = (Math.random() - 0.5) * 0.1 + const dy = (Math.random() - 0.5) * 0.1 + const magnetism = 0.1 + Math.random() * 4 + return { + x, + y, + translateX, + translateY, + size: pSize, + alpha, + targetAlpha, + dx, + dy, + magnetism, + } + } + + const drawCircle = (circle: Circle, update = false) => { + if ( + context.current && + carrotImage.current && + carrotImage.current.complete + ) { + const { x, y, translateX, translateY, size, alpha } = circle + + const aspectRatio = 128 / 79 // Height-to-width ratio + const width = size // Use the size directly for width + const height = size * aspectRatio // Calculate height based on aspect ratio + + context.current.globalAlpha = alpha // Set transparency + context.current.drawImage( + carrotImage.current, + x + translateX - width / 2, // Adjust x position to center the carrot + y + translateY - height / 2, // Adjust y position to center the carrot + width, // Correctly scaled width + height // Correctly scaled height + ) + context.current.globalAlpha = 1 // Reset transparency + + if (!update) { + circles.current.push(circle) + } + } + } + + const clearContext = () => { + if (context.current) { + context.current.clearRect( + 0, + 0, + canvasSize.current.w, + canvasSize.current.h + ) + } + } + + const drawParticles = () => { + clearContext() + const particleCount = quantity + for (let i = 0; i < particleCount; i++) { + const circle = circleParams() + drawCircle(circle) + } + } + + const remapValue = ( + value: number, + start1: number, + end1: number, + start2: number, + end2: number + ): number => { + const remapped = + ((value - start1) * (end2 - start2)) / (end1 - start1) + start2 + return remapped > 0 ? remapped : 0 + } + + const animate = () => { + clearContext() + circles.current.forEach((circle: Circle, i: number) => { + // Handle the alpha value + const edge = [ + circle.x + circle.translateX - circle.size, // distance from left edge + canvasSize.current.w - circle.x - circle.translateX - circle.size, // distance from right edge + circle.y + circle.translateY - circle.size, // distance from top edge + canvasSize.current.h - circle.y - circle.translateY - circle.size, // distance from bottom edge + ] + const closestEdge = edge.reduce((a, b) => Math.min(a, b)) + const remapClosestEdge = parseFloat( + remapValue(closestEdge, 0, 20, 0, 1).toFixed(2) + ) + if (remapClosestEdge > 1) { + circle.alpha += 0.02 + if (circle.alpha > circle.targetAlpha) { + circle.alpha = circle.targetAlpha + } + } else { + circle.alpha = circle.targetAlpha * remapClosestEdge + } + circle.x += circle.dx + vx + circle.y += circle.dy + vy + circle.translateX += + (mouse.current.x / (staticity / circle.magnetism) - circle.translateX) / + ease + circle.translateY += + (mouse.current.y / (staticity / circle.magnetism) - circle.translateY) / + ease + + drawCircle(circle, true) + + // circle gets out of the canvas + if ( + circle.x < -circle.size || + circle.x > canvasSize.current.w + circle.size || + circle.y < -circle.size || + circle.y > canvasSize.current.h + circle.size + ) { + // remove the circle from the array + circles.current.splice(i, 1) + // create a new circle + const newCircle = circleParams() + drawCircle(newCircle) + // update the circle position + } + }) + rafID.current = window.requestAnimationFrame(animate) + } + + return ( + + ) +} + +export default Particles diff --git a/src/components/ui/shine-border.tsx b/src/components/ui/shine-border.tsx new file mode 100644 index 0000000..53b12a8 --- /dev/null +++ b/src/components/ui/shine-border.tsx @@ -0,0 +1,61 @@ +"use client"; + +import { cn } from "@/lib/utils"; + +type TColorProp = string | string[]; + +interface ShineBorderProps { + borderRadius?: number; + borderWidth?: number; + duration?: number; + color?: TColorProp; + className?: string; + children: React.ReactNode; +} + +/** + * @name Shine Border + * @description It is an animated background border effect component with easy to use and configurable props. + * @param borderRadius defines the radius of the border. + * @param borderWidth defines the width of the border. + * @param duration defines the animation duration to be applied on the shining border + * @param color a string or string array to define border color. + * @param className defines the class name to be applied to the component + * @param children contains react node elements. + */ +export default function ShineBorder({ + borderRadius = 8, + borderWidth = 1, + duration = 14, + color = "#000000", + className, + children, +}: ShineBorderProps) { + return ( +
+
+ {children} +
+ ); +} diff --git a/src/components/ui/word-rotate.tsx b/src/components/ui/word-rotate.tsx new file mode 100644 index 0000000..f4427c6 --- /dev/null +++ b/src/components/ui/word-rotate.tsx @@ -0,0 +1,50 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { AnimatePresence, HTMLMotionProps, motion } from "framer-motion"; + +import { cn } from "@/lib/utils"; + +interface WordRotateProps { + words: string[]; + duration?: number; + framerProps?: HTMLMotionProps<"h1">; + className?: string; +} + +export default function WordRotate({ + words, + duration = 2500, + framerProps = { + initial: { opacity: 0, y: -50 }, + animate: { opacity: 1, y: 0 }, + exit: { opacity: 0, y: 50 }, + transition: { duration: 0.25, ease: "easeOut" }, + }, + className, +}: WordRotateProps) { + const [index, setIndex] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setIndex((prevIndex) => (prevIndex + 1) % words.length); + }, duration); + + // Clean up interval on unmount + return () => clearInterval(interval); + }, [words, duration]); + + return ( +
+ + + {words[index]} + + +
+ ); +} diff --git a/tailwind.config.ts b/tailwind.config.ts index a26a5bc..1c137c4 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -57,6 +57,52 @@ export default { md: 'calc(var(--radius) - 2px)', sm: 'calc(var(--radius) - 4px)', }, + animation: { + meteor: 'meteor 5s linear infinite', + 'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear', + shine: 'shine var(--duration) infinite linear', + 'background-position-spin': + 'background-position-spin 3000ms infinite alternate', + }, + keyframes: { + meteor: { + '0%': { + transform: 'rotate(215deg) translateX(0)', + opacity: '1', + }, + '70%': { + opacity: '1', + }, + '100%': { + transform: 'rotate(215deg) translateX(-500px)', + opacity: '0', + }, + }, + 'border-beam': { + '100%': { + 'offset-distance': '100%', + }, + }, + shine: { + '0%': { + 'background-position': '0% 0%', + }, + '50%': { + 'background-position': '100% 100%', + }, + to: { + 'background-position': '0% 0%', + }, + }, + 'background-position-spin': { + '0%': { + backgroundPosition: 'top center', + }, + '100%': { + backgroundPosition: 'bottom center', + }, + }, + }, }, container: { center: true,