diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..9724e2ae --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +node_modules/ +.next/ +out/ +api/ +data-factory/ +portal-app/ +apps/ +automation/ +*.config.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..957cd154 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals"] +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 66e58896..16a23602 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,357 +1,254 @@ -# toolsinc-dashdarkx - Copilot Instructions +# T.O.O.L.S Inc - Copilot Instructions ## Project Overview -This is the **T.O.O.LS Inc DashDarkX** - a Next.js 14 dashboard application with dark theme styling. The project uses React 18, TypeScript, Tailwind CSS, with Framer Motion animations and Recharts for data visualization, deployed as an Azure Static Web App. +**T.O.O.L.S Inc** (Together Overcoming Obstacles and Limitations) is a Next.js 14 web application supporting justice-involved individuals through programs, referrals, and a learning portal. The platform includes public pages, form submissions, authenticated user portal, and AI chatbot support. -## Current Architecture +## Architecture ### Technology Stack -- **Framework**: Next.js 14.2.0 (App Router) -- **React**: 18.3.1 -- **Styling**: Tailwind CSS 3.4.10 + PostCSS, clsx, tailwind-merge +- **Framework**: Next.js 14.2.0 (App Router, Static Export) +- **Styling**: Tailwind CSS 3.4.10 with custom dark theme - **Animation**: Framer Motion 11.0.0 - **Charts**: Recharts 2.12.7 -- **TypeScript**: 5.5.4 -- **Deployment**: Azure Static Web Apps - -### Project State -This project has **core infrastructure** in place: -- Next.js 14 App Router with root layout configured -- Tailwind CSS with custom dark theme design system -- Typography system with responsive heading classes -- Glass morphism UI primitives -- `cn()` utility for class merging -- Reusable component patterns (Button, GlowCard with Framer Motion) -- Full dashboard components (Navbar, SectionHeading, DashboardSection) -- Recharts integration for data visualization -- Complete landing page (`app/page.tsx`) with hero, features, dashboard, and CTA -- Updated Azure deployment workflow with Next.js build -- The `.github/fluentui-master` directory contains a FluentUI monorepo (likely for reference or future integration) +- **Authentication**: React Context (mock implementation, requires backend) +- **Deployment**: Azure Static Web Apps + Docker support + +### Application Structure + +The app has **three main areas**: + +1. **Public Pages** (`app/`): + - `/` - Landing page with hero, features, dashboard preview, CTA + - `/interest` - Interest form with QR code for easy mobile access + - `/referral` - Referral submission form for justice-involved individuals + - `/partnerships` - Partnership information and benefits + +2. **User Portal** (`app/portal/`): + - `/portal/auth` - Login/signup page + - `/portal/dashboard` - User dashboard with stats, progress tracking + - `/portal/courses` - Course catalog with lessons and video content + - `/portal/profile` - User profile management and preferences + +3. **Shared Components** (`components/ui/`): + - Design system: Button, GlowCard, Navbar, SectionHeading + - ChatBot - Floating AI assistant with keyword-based responses + - CookieConsent - GDPR-compliant banner with granular preferences + - DashboardSection - Pre-built dashboard layout with KPIs + - InteractiveTiles - Hover effects for feature showcases ### Next.js Configuration -- **Static Export**: `output: "export"` - generates standalone static HTML/CSS/JS +- **Static Export** (`output: "export"`) - No server-side rendering - **Images**: Unoptimized (required for static export) -- **Trailing Slash**: Enabled for Azure Static Web Apps compatibility -- **Target**: Azure Static Web Apps (no server-side rendering) +- **Trailing Slash**: Enabled for Azure Static Web Apps +- **Path Alias**: `@/` maps to root directory -## Development Workflows +## Critical Workflows -### Running the Development Server +### Development ```bash -npm run dev +npm run dev # Local dev server (http://localhost:3000) +npm run build # Production build +npm run export # Build + static export to /out +npm run lint # ESLint checks ``` -Starts Next.js development server (default: http://localhost:3000) -### Building for Production +### Docker (Optional) ```bash -npm run build # Standard build -npm run export # Build + static export for hosting -npm run start # Preview production build +npm run docker:build # Build Docker image +npm run docker:run # Run container on port 3000 +npm run compose:up # Docker Compose stack ``` +See [DOCKER.md](../DOCKER.md) for Azure Container Registry and ACI deployment. -### Linting -```bash -npm run lint -``` +### Azure Deployment +- **Trigger**: Push to `main` or pull request +- **Workflow**: `.github/workflows/azure-static-web-apps-blue-desert-08d808f10.yml` +- **Process**: + 1. Install dependencies with `npm ci` + 2. Build with `npm run build` (Node 20, 4GB memory) + 3. Deploy `/out` directory to Azure Static Web Apps +- **PR Previews**: Automatic staging environments for pull requests -## Deployment - -### Azure Static Web Apps -- **Deployment Trigger**: Push to `main` branch or pull request -- **Workflow**: `.github/workflows/azure-static-web-apps-red-river-01c6ba710.yml` -- **Configuration**: - - Node.js 20 with npm cache - - Runs `npm ci` then `npm run export` - - App location: `/` (root) - - Output location: `out` (Next.js static export) - - Includes PR preview deployments - -## Important Conventions - -### When Creating Next.js Structure -When implementing the Next.js application, follow these guidelines: - -1. **Use App Router** (Next.js 14 default): - - Create `app/` directory for routes - - Use Server Components by default - - Add `'use client'` directive only when needed (client-side interactivity, hooks, event handlers) - -2. **TypeScript Files**: - - Use `.tsx` for components - - Use `.ts` for utilities and non-component files - - Maintain strict TypeScript configurations - -3. **Tailwind CSS + Utility Libraries**: - - Config: `tailwind.config.ts`, `postcss.config.js` - - Content paths: `./app/**/*.{ts,tsx}`, `./components/**/*.{ts,tsx}` - - `app/globals.css` - Tailwind directives + custom utilities - - Use `clsx` for conditional class names - - Use `tailwind-merge` via `cn()` utility to merge Tailwind classes safely - - **Dark Theme Design System**: - - Background: `bg-bg` (#06070b), `bg-panel` (#0c0f17) - - Glass effects: `bg-glass` (rgba overlay) or `.glass` utility class - - Borders: `border-border` (rgba white 12%) - - Text: `text-text` (slate-50 96%), `text-muted` (slate-400 92%) - - Brand colors: `text-brand` (#38bdf8 sky), `text-brand2` (#2dd4bf teal), `text-accent` (#a78bfa purple) - - Glow effects: `shadow-glow`, `bg-dash-glow` (radial gradients) - - Custom radii: `rounded-xl` (26px), `rounded-lg` (18px), `rounded-md` (12px) - - Font: Inter (`font-sans`) - - Container: `max-w-container` (1200px) - - **Typography System** (Webflow/DashDark-style): - - `.h1` - 42px/56px/72px, tracking-tight2, font-extrabold (responsive) - - `.h2` - 28px/34px/40px, tracking-tight2, font-extrabold (responsive) - - `.p-lead` - 16px/18px, text-muted, leading-[1.7] - -4. **Animation & Data Visualization**: - - **Framer Motion**: For smooth animations and transitions - - **Recharts**: For dashboard charts and data visualization - - Both require `'use client'` directive when used - -5. **Component Organization**: - - Place reusable UI components in `components/ui/` - - Use `@/` path alias for imports (e.g., `@/lib/cn`, `@/components/ui/Button`) - - Client components go in files marked with `'use client'` directive - - Export component types alongside component for type safety - -### FluentUI Integration -The `.github/fluentui-master/` directory contains Microsoft FluentUI codebase. If integrating FluentUI: -- Reference the `AGENTS.md` for Nx workspace patterns -- FluentUI uses Nx monorepo architecture with `nx` commands -- Consider if FluentUI React v9 components are needed - -## Key Files & Directories - -- `package.json` - Dependencies and scripts -- `next.config.js` - Next.js configuration (static export, images, trailing slash) -- `tailwind.config.ts` - Dark theme design system (colors, spacing, typography) -- `postcss.config.js` - PostCSS with Tailwind and Autoprefixer -- `app/layout.tsx` - Root layout with metadata and font configuration -- `app/page.tsx` - Landing page with hero, features, dashboard, CTA -- `app/globals.css` - Tailwind directives + custom typography + glass utilities -- `lib/cn.ts` - Utility for merging Tailwind classes with clsx + tailwind-merge -- `components/ui/Button.tsx` - Animated button component with variants -- `components/ui/GlowCard.tsx` - Glass card with scroll animations and hover glow -- `components/ui/SectionHeading.tsx` - Section header with eyebrow/title/subtitle -- `components/ui/Navbar.tsx` - Sticky navigation header with backdrop blur -- `components/ui/DashboardSection.tsx` - Full dashboard layout with charts, KPIs, tables -- `.github/workflows/` - Azure deployment pipeline -- `.github/fluentui-master/` - FluentUI reference codebase (Nx monorepo) -- `.next/` - Next.js build output (gitignored) -- `out/` - Static export output (gitignored) -- `.env` - Environment variables (gitignored) - -## Next Steps for Development - -When building out the application: - -1. **Core Structure Complete** ✅: - ``` - app/ - layout.tsx # Root layout with Inter font (exists) - page.tsx # Landing page with full sections (exists) - globals.css # Tailwind + custom utilities (exists) - components/ - ui/ - Button.tsx # Animated button component (exists) - GlowCard.tsx # Glass card with animations (exists) - SectionHeading.tsx # Section header pattern (exists) - Navbar.tsx # Sticky navigation (exists) - DashboardSection.tsx # Full dashboard (exists) - lib/ - cn.ts # Class name utility (exists) - ``` +## Design System -2. **Design System Ready** ✅: - - `tailwind.config.ts` - Dark theme configured - - `postcss.config.js` - Build pipeline configured - - `app/globals.css` - Custom utilities (.h1, .h2, .glass) ready - - Typography system, glass effects, and color tokens available - -3. **Component Library Started** ✅: - - `lib/cn.ts` - Class name utility implemented - - `components/ui/Button.tsx` - Animated button with variants - - `components/ui/GlowCard.tsx` - Glass card with scroll/hover animations - - `components/ui/SectionHeading.tsx` - Section header with eyebrow pattern - - `components/ui/Navbar.tsx` - Sticky nav with backdrop blur - - `components/ui/DashboardSection.tsx` - Full dashboard with KPIs, charts, tables - - Pattern established for future components - -4. **Next: Build Pages**: - - ✅ `app/page.tsx` implemented with hero, features, dashboard, CTA - - ✅ Azure deployment workflow updated to build Next.js - - ✅ Static export configured for Azure Static Web Apps - - Ready to extend with additional pages or features as needed - -4. **Replace Static HTML**: - - Remove `index.html` once Next.js routes are ready - - Update Azure Static Web App workflow to enable Next.js build - - Remove `index.html` once Next.js routes are ready - - Update Azure Static Web App workflow to enable Next.js build - -4. **Environment Configuration**: - - Use `.env.local` for local secrets - - Configure Azure Static Web Apps environment variables in portal - -## Useful Commands - -```bash -# Development -npm run dev # Start dev server -npm run build # Production build -npm run export # Build + static export -npm run start # Serve production build -npm run lint # Run ESLint - -# Next.js specific -npx next info # Display Next.js environment info +### Dark Theme Tokens (Tailwind) +```typescript +colors: { + bg: "#06070b", // Main background + panel: "#0c0f17", // Card/panel background + glass: "rgba(255,255,255,.06)", // Glass overlay + border: "rgba(255,255,255,.12)", // Border color + text: "rgba(248,250,252,.96)", // Primary text + muted: "rgba(148,163,184,.92)", // Secondary text + brand: "#38bdf8", // Sky blue (primary brand) + brand2: "#2dd4bf", // Teal (secondary brand) + accent: "#a78bfa" // Purple (accent) +} ``` -## Common Patterns +### Typography System (Custom CSS Classes) +```css +.h1 - 42px/56px/72px (responsive), tracking-tight2, font-extrabold +.h2 - 28px/34px/40px (responsive), tracking-tight2, font-extrabold +.p-lead - 16px/18px, text-muted, leading-[1.7] +``` -### cn() Utility for Class Names -Implemented in `lib/cn.ts` for merging Tailwind classes: -```typescript -import { clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; +### Glass Morphism Pattern +```tsx +// Option 1: Utility class +
| Header | -
|---|
| Cell | -
Description
-Lead paragraph with muted text
-``` - ---- +## Important Notes + +### Authentication Security +⚠️ **WARNING**: Current auth is a **mock implementation** for development only: +- Passwords stored in plain text in localStorage +- No encryption, only Base64 encoding +- No backend validation + +**Before Production**: +1. Implement secure backend API (Node.js/Express, ASP.NET, etc.) +2. Use proper password hashing (bcrypt, argon2) +3. Implement JWT or session-based auth +4. Add HTTPS-only, HttpOnly cookies +5. Never expose secrets in client-side code + +### Static Export Limitations +Because `output: "export"` is enabled: +- No server-side rendering (SSR) +- No API routes (`app/api/` won't work) +- No dynamic routing with `getServerSideProps` +- No Image Optimization (use `unoptimized: true`) + +### FluentUI Reference +The `.github/fluentui-master/` directory is a FluentUI monorepo (likely for reference). If integrating: +- Uses Nx workspace (`nx` commands) +- See `AGENTS.md` for Nx patterns +- FluentUI React v9 components available + +## Common Tasks + +### Adding a New Public Page +1. Create `app/new-page/page.tsx` +2. Use standard page structure (see **Page Structure** pattern) +3. Include `At T.O.O.L.S Inc, we provide support and opportunities for individuals looking to start over. Through comprehensive programs and lived experience, we help people unlock their full potential.
We recognize and address the diverse challenges individuals face, providing the tools and support necessary to unlock their full potential.
Choose an action below to get started with our services, or chat with MackAi for instant assistance.
Let us know how we can support you
Refer someone who could benefit from our programs
Get instant answers to your questions
Explore our comprehensive support services
A compassionate advocate and the driving force behind T.O.O.L.S Inc, Donyale Mack is dedicated to providing support and opportunities to those seeking a second chance in life.
Born out of lived experience and personal challenges, Donyale's journey is marked by resilience, overcoming adversity, and an unwavering passion to help others facing similar struggles.
"Every individual deserves the opportunity to unlock their full potential."
Creating pathways for individuals to transform their lives through empathy, understanding, and comprehensive support programs.
Building a community where lived experience becomes the foundation for genuine connection and lasting change.
Combining personal understanding with professional expertise to provide support that goes beyond sympathy to true empowerment.
Track participant progress, program outcomes, and community impact with comprehensive metrics and reporting.
| Date | Activity | Program | Participants | Status |
|---|---|---|---|---|
| Mon 1/13 | Resume Workshop | Job Readiness | 12 | Confirmed |
| Tue 1/14 | Mock Interviews | Job Readiness | 6 | Scheduled |
| Wed 1/15 | Career Counseling | Mentorship | 8 | In Progress |
| Thu 1/16 | Skills Assessment | Education | 15 | Pending |
A portion of the proceeds go to helping program participants with immediate needs such as but not limited to: bus/transit passes, gas cards, work boots and clothing for work.
We appreciate Your Support
Let us know how we can support you. Fill out the form below and we'll respond within 48 hours.
Scan to fill out the Interest Form
If filling this form out for a loved one, friend or family member please be sure to put all information so that contact can be made. If the individual is currently incarcerated please fill out this form with your contact information and someone will reach out to you within 48 hours.
Thank You for Your Support!
Need immediate assistance? Contact us directly
16)throw Error(cV+c4(t));if(!t.s)return new l(cB);for(null==e?(cH=!1,a=s):a=e,i=new l(.03125);t.abs().gte(.1);)t=t.times(i),u+=5;for(a+=Math.log(cZ(2,u))/Math.LN10*2+5|0,r=n=o=new l(cB),l.precision=a;;){if(n=ut(n.times(t),a),r=r.times(++c),c2((i=o.plus(c3(n,r,a))).d).slice(0,a)===c2(o.d).slice(0,a)){for(;u--;)o=ut(o.times(o),a);return l.precision=s,null==e?(cH=!0,ut(o,s)):o}o=i}}function c4(t){for(var e=7*t.e,r=t.d[0];r>=10;r/=10)e++;return e}function c5(t,e,r){if(e>t.LN10.sd())throw cH=!0,r&&(t.precision=r),Error(cX+"LN10 precision limit exceeded");return ut(new t(t.LN10),e)}function c8(t){for(var e="";t--;)e+="0";return e}function c7(t,e){var r,n,o,i,a,c,u,l,s,f=1,p=t,h=p.d,d=p.constructor,y=d.precision;if(p.s<1)throw Error(cX+(p.s?"NaN":"-Infinity"));if(p.eq(cB))return new d(0);if(null==e?(cH=!1,l=y):l=e,p.eq(10))return null==e&&(cH=!0),c5(d,l);if(l+=10,d.precision=l,n=(r=c2(h)).charAt(0),!(15e14>Math.abs(i=c4(p))))return u=c5(d,l+2,y).times(i+""),p=c7(new d(n+"."+r.slice(1)),l-10).plus(u),d.precision=y,null==e?(cH=!0,ut(p,y)):p;for(;n<7&&1!=n||1==n&&r.charAt(1)>3;)n=(r=c2((p=p.times(t)).d)).charAt(0),f++;for(i=c4(p),n>1?(p=new d("0."+r),i++):p=new d(n+"."+r.slice(1)),c=a=p=c3(p.minus(cB),p.plus(cB),l),s=ut(p.times(p),l),o=3;;){if(a=ut(a.times(s),l),c2((u=c.plus(c3(a,new d(o),l))).d).slice(0,l)===c2(c.d).slice(0,l))return c=c.times(2),0!==i&&(c=c.plus(c5(d,l+2,y).times(i+""))),c=c3(c,new d(f),l),d.precision=y,null==e?(cH=!0,ut(c,y)):c;c=u,o+=2}}function c9(t,e){var r,n,o;for((r=e.indexOf("."))>-1&&(e=e.replace(".","")),(n=e.search(/e/i))>0?(r<0&&(r=n),r+=+e.slice(n+1),e=e.substring(0,n)):r<0&&(r=e.length),n=0;48===e.charCodeAt(n);)++n;for(o=e.length;48===e.charCodeAt(o-1);)--o;if(e=e.slice(n,o)){if(o-=n,r=r-n-1,t.e=cY(r/7),t.d=[],n=(r+1)%7,r<0&&(n+=7),n Together, we're building a stronger community through strategic partnerships and collaborative support networks. Connecting individuals with experienced mentors who provide guidance, support, and real-world insights for personal and professional growth. Working together to provide comprehensive services and resources to our community. United in our commitment to empowering individuals and creating lasting positive change. Combining expertise and resources to maximize impact and reach more people in need. Leveraging cutting-edge platforms and tools to build innovative solutions for our community. Open source development and version control platform powering our digital infrastructure. Justice Involved Need assistance? Contact us=s&&f<=l}return r?lR(lR({},e),{},{radius:o,angle:f+360*Math.min(Math.floor(e.startAngle/360),Math.floor(e.endAngle/360))}):null};function lq(t){return(lq="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lH=["offset"];function lX(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r{var n=r(6245),o=r(9377),i=r(4111),a=r(2317),c=r(9616),u=r(8874),l=n?n.prototype:void 0,s=l?l.valueOf:void 0;t.exports=function(t,e,r,n,l,f,p){switch(r){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)break;t=t.buffer,e=e.buffer;case"[object ArrayBuffer]":if(t.byteLength!=e.byteLength||!f(new o(t),new o(e)))break;return!0;case"[object Boolean]":case"[object Date]":case"[object Number]":return i(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var h=c;case"[object Set]":var d=1&n;if(h||(h=u),t.size!=e.size&&!d)break;var y=p.get(t);if(y)return y==e;n|=2,p.set(t,e);var v=a(h(t),h(e),n,l,f,p);return p.delete(t),v;case"[object Symbol]":if(s)return s.call(t)==s.call(e)}return!1}},1958:(t,e,r)=>{var n=r(67),o=Object.prototype.hasOwnProperty;t.exports=function(t,e,r,i,a,c){var u=1&r,l=n(t),s=l.length;if(s!=n(e).length&&!u)return!1;for(var f=s;f--;){var p=l[f];if(!(u?p in e:o.call(e,p)))return!1}var h=c.get(t),d=c.get(e);if(h&&d)return h==e&&d==t;var y=!0;c.set(t,e),c.set(e,t);for(var v=u;++f{var e="object"==typeof global&&global&&global.Object===Object&&global;t.exports=e},67:(t,e,r)=>{var n=r(4003),o=r(6102),i=r(5865);t.exports=function(t){return n(t,i,o)}},4326:(t,e,r)=>{var n=r(4587);t.exports=function(t,e){var r=t.__data__;return n(e)?r["string"==typeof e?"string":"hash"]:r.map}},5906:(t,e,r)=>{var n=r(1623),o=r(5865);t.exports=function(t){for(var e=o(t),r=e.length;r--;){var i=e[r],a=t[i];e[r]=[i,a,n(a)]}return e}},7017:(t,e,r)=>{var n=r(4104),o=r(2751);t.exports=function(t,e){var r=o(t,e);return n(r)?r:void 0}},9083:(t,e,r)=>{var n=r(7181)(Object.getPrototypeOf,Object);t.exports=n},4244:(t,e,r)=>{var n=r(6245),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,c=n?n.toStringTag:void 0;t.exports=function(t){var e=i.call(t,c),r=t[c];try{t[c]=void 0;var n=!0}catch(t){}var o=a.call(t);return n&&(e?t[c]=r:delete t[c]),o}},6102:(t,e,r)=>{var n=r(7536),o=r(5252),i=Object.prototype.propertyIsEnumerable,a=Object.getOwnPropertySymbols,c=a?function(t){return null==t?[]:n(a(t=Object(t)),function(e){return i.call(t,e)})}:o;t.exports=c},4963:(t,e,r)=>{var n=r(4654),o=r(7926),i=r(9186),a=r(9746),c=r(5803),u=r(1534),l=r(1708),s="[object Map]",f="[object Promise]",p="[object Set]",h="[object WeakMap]",d="[object DataView]",y=l(n),v=l(o),m=l(i),b=l(a),g=l(c),x=u;(n&&x(new n(new ArrayBuffer(1)))!=d||o&&x(new o)!=s||i&&x(i.resolve())!=f||a&&x(new a)!=p||c&&x(new c)!=h)&&(x=function(t){var e=u(t),r="[object Object]"==e?t.constructor:void 0,n=r?l(r):"";if(n)switch(n){case y:return d;case v:return s;case m:return f;case b:return p;case g:return h}return e}),t.exports=x},2751:t=>{t.exports=function(t,e){return null==t?void 0:t[e]}},3932:(t,e,r)=>{var n=r(204),o=r(6148),i=r(2966),a=r(9699),c=r(9002),u=r(1094);t.exports=function(t,e,r){e=n(e,t);for(var l=-1,s=e.length,f=!1;++l{var e=RegExp("[\\u200d\ud800-\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");t.exports=function(t){return e.test(t)}},7392:(t,e,r)=>{var n=r(7193);t.exports=function(){this.__data__=n?n(null):{},this.size=0}},9247:t=>{t.exports=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}},4190:(t,e,r)=>{var n=r(7193),o=Object.prototype.hasOwnProperty;t.exports=function(t){var e=this.__data__;if(n){var r=e[t];return"__lodash_hash_undefined__"===r?void 0:r}return o.call(e,t)?e[t]:void 0}},6193:(t,e,r)=>{var n=r(7193),o=Object.prototype.hasOwnProperty;t.exports=function(t){var e=this.__data__;return n?void 0!==e[t]:o.call(e,t)}},6681:(t,e,r)=>{var n=r(7193);t.exports=function(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=n&&void 0===e?"__lodash_hash_undefined__":e,this}},2565:(t,e,r)=>{var n=r(6245),o=r(6148),i=r(2966),a=n?n.isConcatSpreadable:void 0;t.exports=function(t){return i(t)||o(t)||!!(a&&t&&t[a])}},9699:t=>{var e=/^(?:0|[1-9]\d*)$/;t.exports=function(t,r){var n=typeof t;return!!(r=null==r?9007199254740991:r)&&("number"==n||"symbol"!=n&&e.test(t))&&t>-1&&t%1==0&&tIn Partnership



Our Mentorship Program




Technology Partners
GitHub
Referral Form
404
This page could not be found.