Compare commits

...
81 Commits
Author SHA1 Message Date
ace bb7211f230 feat: add CardTitle, CardDescription, CardFooter components 2026-03-14 00:03:07 +01:00
ace 94beb7da78 test commit 2025-12-15 14:19:25 +01:00
ace 1f7b90b816 fix: add ignoreDeprecations to mobile tsconfig to suppress baseUrl warning 2025-12-15 13:13:31 +01:00
ace 04856021b9 feat: add refresh button to geofencing status card 2025-12-15 13:05:21 +01:00
ace c238e18766 fix: remove unsupported gap style from GeofenceStatus 2025-12-15 12:31:55 +01:00
ace 0c272502f8 feat: add simple geofence status card to attendance screen - demo mode 2025-12-15 12:25:56 +01:00
ace 231ad44cc4 fix: tsconfig ignoreDeprecations and GeofenceStatus component - use GYM_LOCATION constant 2025-12-15 12:19:27 +01:00
ace 2f79d1547f feat: enhance UI with metallic gradient cards - admin and mobile consistent color schemes 2025-12-15 12:10:44 +01:00
ace 337351dd06 fix: add ignoreDeprecations to tsconfig.json to silence baseUrl deprecation warning 2025-12-15 10:38:32 +01:00
ace fe3f93fb9f style: increase NextForm logo size across all components 2025-12-11 14:49:15 +01:00
ace 3c810003c5 feat: integrate NextForm PNG logo across admin and mobile applications 2025-12-11 14:48:12 +01:00
ace 6207949e2d fix: use nextform.png logo across all components 2025-12-11 14:39:15 +01:00
ace 76b9ee24c5 style: update sidebar and dashboard with NextForm branding 2025-12-11 14:28:10 +01:00
ace ad6fdc2226 feat: add NextForm logo to admin navigation, dashboard header and mobile home screen 2025-12-11 14:24:37 +01:00
ace 8c2a3daee0 style: apply kameleon gradient transitions to analytics cards - all metrics and charts with via-colors 2025-12-11 14:16:41 +01:00
ace 19ece90c6f style: adjust card sizing to balanced medium - between original and enlarged 2025-12-11 14:15:28 +01:00
ace b9efedbb88 style: add chameleon gradient transitions with via colors for smooth color blending 2025-12-11 14:13:10 +01:00
ace 204e6edca5 style: apply strong gradient colors to stats cards instead of light backgrounds 2025-12-11 14:11:22 +01:00
ace 918357c00c fix: add missing CardTitle, CardDescription and CardFooter exports to Card component 2025-12-11 14:10:33 +01:00
ace 4fbe8399df fix: add card.ts compatibility layer for lowercase Card imports 2025-12-11 14:09:37 +01:00
ace 61bad8d30c fix: add button.ts compatibility layer and fix all Button imports to use lowercase 2025-12-11 14:08:58 +01:00
ace 966bcb084d style: implement dark gradient metric cards with high contrast white text and colored labels 2025-12-11 14:01:32 +01:00
ace 71a05c51bf fix: update mobile metric cards with proper 500-range vibrant colors matching admin dashboard 2025-12-11 14:00:03 +01:00
ace e4eadc858c style: strengthen performance metrics colors with darker gradients and brighter white text 2025-12-11 13:56:18 +01:00
ace 0024510fdb feat: add performance metrics dashboard to mobile home screen with gradient cards 2025-12-11 13:54:01 +01:00
ace c9fbab3bbb style: revert background to light theme and update card colors to match sidebar palette 2025-12-11 13:51:36 +01:00
ace 35d64ef3c0 style: apply bold modern colors throughout dashboard - dark backgrounds, vibrant gradients, white text 2025-12-11 13:48:30 +01:00
ace 6dc90f1745 feat: reorganize dashboard layout with UserManagement full-width and horizontal analytics charts 2025-12-11 13:44:02 +01:00
ace 02452c11e6 fix: simplify AnalyticsDashboard layout to prevent text overflow and improve stability 2025-12-11 13:41:57 +01:00
ace dd78602dd6 style: improve UserManagement layout with flex-wrap and better organization 2025-12-11 13:39:42 +01:00
ace 0a55438bce fix: remove extra closing brace in StatsCard 2025-12-11 13:38:03 +01:00
ace 51df7f57ec style: compact stats cards with better colors and layout 2025-12-11 13:37:01 +01:00
ace feacef2a81 fix: remove all duplicate closing tags in StatsCard 2025-12-11 13:35:37 +01:00
ace 77546a5017 fix: remove duplicate code in StatsCard 2025-12-11 13:34:40 +01:00
ace d38f0a4cc2 style: enhance card colors and improve typography hierarchy 2025-12-11 13:32:35 +01:00
ace b6764b5ed6 fix: remove duplicate closing brackets in Sidebar 2025-12-11 13:29:36 +01:00
ace e84d0f5f8f feat: modernize admin dashboard with premium sports design 2025-12-11 13:27:57 +01:00
ace fda66a7703 fix: completely disable camera/barcode on web platform 2025-12-11 13:23:56 +01:00
ace 2d9fbd186b fix: disable barcode scanner on web platform 2025-12-11 13:19:09 +01:00
ace bbd0cfde9c fix: add platform check for WebBrowser warmUpAsync on web 2025-12-11 13:15:33 +01:00
ace 16e22f330a fix: update route params to Promise type for Next.js 16 compatibility 2025-12-11 13:10:51 +01:00
ace efa2f2a8d8 fix: correct Button import paths to use lowercase button 2025-12-11 13:04:50 +01:00
dimitar 62e2255b5e fix 2025-12-01 23:17:40 +01:00
dimitar d7d270510f c 2025-12-01 21:10:04 +01:00
dimitar a5c297b911 ups 2025-12-01 21:09:35 +01:00
dimitar 0011c9d4e5 currently check in implemented 2025-12-01 20:07:48 +01:00
dimitar db0d2cf215 scan food
with mock db, real db[openfoodfacts] to be implemented
2025-12-01 19:49:10 +01:00
dimitar ec370a3c17 track meal and add water implemented 2025-12-01 19:31:07 +01:00
dimitar b0d751540e ngrok 2025-11-26 03:45:52 +01:00
dimitar 06237579f0 fix with stackview 2025-11-26 03:10:39 +01:00
dimitar c038a54f2e fitness profileand personal details
fix
2025-11-26 02:59:53 +01:00
dimitar b014734f33 db up 2025-11-26 02:41:44 +01:00
dimitar fe98c13206 db permisions fixed 2025-11-26 02:36:19 +01:00
dimitar febcdc111e redesign completed
alot of work ahead
2025-11-26 02:31:46 +01:00
dimitar 73d2c4c1ed claude take :( 2025-11-26 01:57:33 +01:00
dimitar fc12cecd30 db up 2025-11-26 01:34:10 +01:00
dimitar 803c205994 context and goals definition added 2025-11-26 01:30:15 +01:00
dimitar 28b5b52a8f context extended
maybe need polishing
2025-11-26 01:13:11 +01:00
dimitar 684481fd2c db consolidation done 2025-11-26 00:54:27 +01:00
dimitar bf532ba35d deepseek integrated succesfully 2025-11-24 19:25:34 +01:00
dimitar 0896dd46d1 ai rec refinement 2025-11-24 19:08:58 +01:00
dimitar e9ba9e2700 recommendatio edit added 2025-11-24 18:36:04 +01:00
dimitar 3ab9908588 ai rec works
as intended, needs refinments
2025-11-24 17:57:35 +01:00
dimitar 0183a8ea6a fitnees profile fix in user page 2025-11-23 18:15:43 +01:00
dimitar 5d1d881f16 db url fix in drizzle config 2025-11-23 17:32:01 +01:00
dimitar 1b50bfd2ee api calls simplified 2025-11-23 17:12:14 +01:00
dimitar 6cbed4e8d1 deps 2025-11-23 16:57:21 +01:00
dimitar 76dafe9cd5 fix deps 2025-11-23 16:39:02 +01:00
dimitar a96f1902c5 social login
implemented, we can add more providers later
2025-11-20 19:28:39 +01:00
dimitar 8b4cef33dc recommendation flow implemented
POC phase compleated
2025-11-20 19:10:16 +01:00
dimitar 118efad70f invite and saving fitness profile
added, need polishing
2025-11-20 18:36:40 +01:00
dimitar daaf5aa2dd attendace view in admin up fixed 2025-11-19 06:10:53 +01:00
dimitar 67636120d6 Merge branch 'superAdmin' 2025-11-19 05:14:36 +01:00
dimitar 892cf1a040 organize docs 2025-11-19 05:12:19 +01:00
dimitar 4909815807 minir fix 2025-11-19 05:07:14 +01:00
dimitar a87b94219d super admin added 2025-11-19 04:00:03 +01:00
dimitar b1bb5d8166 redesign
admin dashboard
2025-11-19 03:34:18 +01:00
dimitar 39021dca35 manual check in/check out
implemented, to be implemented: qrcode or/and geofence
2025-11-19 02:23:39 +01:00
dimitar 33a698066f docs
docs added
2025-11-19 00:47:31 +01:00
dimitar 55ae37f304 docs updated
strategy
2025-11-13 19:22:20 +01:00
dimitar b9f33fdcc6 fitness profile
functionality added, need polishing
2025-11-11 02:16:29 +01:00
307 changed files with 31085 additions and 2160 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# DeepSeek AI API Key
# Get your API key from https://platform.deepseek.com/
DEEPSEEK_API_KEY=your_deepseek_api_key_here
+2 -3
View File
@@ -12,7 +12,6 @@
},
"aliases": {
"components": "@/components",
"utils": "@/lib",
"ui": "@/components/ui"
"utils": "@/lib/utils"
}
}
}
Regular → Executable
BIN
View File
Binary file not shown.
+36
View File
@@ -0,0 +1,36 @@
[Approve] Updating recommendation a2a4d10a-463d-4648-b2a3-3b97fd053078 with: {"status":"approved","approvedAt":"2025-11-24T16:18:30.211Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for a2a4d10a-463d-4648-b2a3-3b97fd053078: {"changes":0,"lastInsertRowid":0}
[SQLite] Fetch after update for a2a4d10a-463d-4648-b2a3-3b97fd053078: Not Found
[Approve] Result for a2a4d10a-463d-4648-b2a3-3b97fd053078: Not Found
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:21:37.787Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":1}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:22:27.297Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":1}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:24:28.104Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":0}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:24:29.552Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":0}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:25:42.561Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":0}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:25:43.627Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":0}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"approved","approvedAt":"2025-11-24T16:27:02.858Z","approvedBy":"user_35fyZb2QT54VYzLfvx1cSIdcnKI"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":2}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
[Approve] Updating recommendation fdacfa23-0116-452b-a40e-671583a6ce60 with: {"status":"rejected"}
[SQLite] Update result for fdacfa23-0116-452b-a40e-671583a6ce60: {"changes":1,"lastInsertRowid":2}
[SQLite] Fetch after update for fdacfa23-0116-452b-a40e-671583a6ce60: Found
[Approve] Result for fdacfa23-0116-452b-a40e-671583a6ce60: Success
+1164 -1085
View File
File diff suppressed because it is too large. Load diff
+12 -4
View File
@@ -12,9 +12,10 @@
},
"dependencies": {
"@clerk/nextjs": "^6.34.5",
"@fitai/database": "file:../../packages/database",
"@fitai/shared": "file:../../packages/shared",
"@hookform/resolvers": "^5.2.2",
"@tailwindcss/postcss": "^4.1.17",
"@radix-ui/react-slot": "^1.2.4",
"@tanstack/react-query": "^5.90.7",
"@types/bcryptjs": "^3.0.0",
"@types/sqlite3": "^5.1.0",
@@ -22,12 +23,17 @@
"ag-charts-react": "^12.3.1",
"ag-grid-community": "^34.3.1",
"ag-grid-react": "^34.3.1",
"autoprefixer": "^10.4.21",
"autoprefixer": "^10.4.16",
"axios": "^1.13.2",
"bcryptjs": "^3.0.3",
"better-sqlite3": "^11.10.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"drizzle-orm": "^0.44.7",
"lucide-react": "^0.553.0",
"next": "^16.0.1",
"postcss": "^8.5.6",
"postcss": "^8.4.31",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.66.0",
@@ -35,7 +41,9 @@
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"svix": "^1.81.0",
"tailwindcss": "^4.1.17",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",
"zod": "^4.1.12"
},
"devDependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
module.exports = {
plugins: {
"@tailwindcss/postcss": {},
tailwindcss: {},
autoprefixer: {},
},
};
+28
View File
@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#2FB7E8;stop-opacity:1" />
<stop offset="50%" style="stop-color:#0B9FD0;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0B7FB3;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Main arrow shape -->
<path d="M 420 150 L 540 150 L 420 300 Z" fill="url(#grad1)" opacity="0.95"/>
<path d="M 180 150 L 300 300 L 180 300 Z" fill="url(#grad1)" opacity="0.85"/>
<!-- Dumbbell - Left -->
<g transform="translate(200, 250)">
<!-- Left disk -->
<circle cx="0" cy="0" r="35" fill="white" opacity="0.95"/>
<!-- Bar left -->
<rect x="35" y="-15" width="80" height="30" fill="white" rx="4"/>
<!-- Right disk -->
<circle cx="115" cy="0" r="35" fill="white" opacity="0.95"/>
<!-- Grip lines -->
<line x1="45" y1="-35" x2="45" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="65" y1="-35" x2="65" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="85" y1="-35" x2="85" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="105" y1="-35" x2="105" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+28
View File
@@ -0,0 +1,28 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#2FB7E8;stop-opacity:1" />
<stop offset="50%" style="stop-color:#0B9FD0;stop-opacity:1" />
<stop offset="100%" style="stop-color:#0B7FB3;stop-opacity:1" />
</linearGradient>
</defs>
<!-- Main arrow shape -->
<path d="M 420 150 L 540 150 L 420 300 Z" fill="url(#grad1)" opacity="0.95"/>
<path d="M 180 150 L 300 300 L 180 300 Z" fill="url(#grad1)" opacity="0.85"/>
<!-- Dumbbell - Left -->
<g transform="translate(200, 250)">
<!-- Left disk -->
<circle cx="0" cy="0" r="35" fill="white" opacity="0.95"/>
<!-- Bar left -->
<rect x="35" y="-15" width="80" height="30" fill="white" rx="4"/>
<!-- Right disk -->
<circle cx="115" cy="0" r="35" fill="white" opacity="0.95"/>
<!-- Grip lines -->
<line x1="45" y1="-35" x2="45" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="65" y1="-35" x2="65" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="85" y1="-35" x2="85" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
<line x1="105" y1="-35" x2="105" y2="35" stroke="url(#grad1)" stroke-width="3" opacity="0.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+1
View File
@@ -0,0 +1 @@
PNG - NextForm Logo
@@ -0,0 +1,49 @@
const Database = require('better-sqlite3');
const path = require('path');
const dbPath = path.join(__dirname, '../data/fitai.db');
const db = new Database(dbPath);
console.log('Creating fitness_goals table...');
try {
db.exec(`
CREATE TABLE IF NOT EXISTS fitness_goals (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
fitness_profile_id TEXT,
goal_type TEXT NOT NULL CHECK(goal_type IN ('weight_target', 'strength_milestone', 'endurance_target', 'flexibility_goal', 'habit_building', 'custom')),
title TEXT NOT NULL,
description TEXT,
target_value REAL,
current_value REAL,
unit TEXT,
start_date INTEGER NOT NULL,
target_date INTEGER,
completed_date INTEGER,
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'abandoned', 'paused')),
progress REAL DEFAULT 0,
priority TEXT DEFAULT 'medium' CHECK(priority IN ('low', 'medium', 'high')),
notes TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (fitness_profile_id) REFERENCES fitness_profiles(userId) ON DELETE CASCADE
)
`);
// Create indexes for better query performance
db.exec(`
CREATE INDEX IF NOT EXISTS idx_fitness_goals_user_id ON fitness_goals(user_id);
CREATE INDEX IF NOT EXISTS idx_fitness_goals_status ON fitness_goals(status);
CREATE INDEX IF NOT EXISTS idx_fitness_goals_profile_id ON fitness_goals(fitness_profile_id);
`);
console.log('✅ fitness_goals table created successfully');
console.log('✅ Indexes created successfully');
} catch (error) {
console.error('❌ Migration failed:', error);
process.exit(1);
} finally {
db.close();
}
@@ -0,0 +1,33 @@
const Database = require('better-sqlite3');
const path = require('path');
const dbPath = path.join(__dirname, '../data/fitai.db');
const db = new Database(dbPath);
console.log('Migrating fitness_profiles table...');
try {
// Check if columns exist
const tableInfo = db.prepare('PRAGMA table_info(fitness_profiles)').all();
const columns = tableInfo.map(c => c.name);
if (!columns.includes('allergies')) {
console.log('Adding allergies column...');
db.prepare('ALTER TABLE fitness_profiles ADD COLUMN allergies TEXT').run();
} else {
console.log('allergies column already exists.');
}
if (!columns.includes('injuries')) {
console.log('Adding injuries column...');
db.prepare('ALTER TABLE fitness_profiles ADD COLUMN injuries TEXT').run();
} else {
console.log('injuries column already exists.');
}
console.log('Migration completed successfully.');
} catch (error) {
console.error('Migration failed:', error);
} finally {
db.close();
}
+19
View File
@@ -0,0 +1,19 @@
const Database = require('better-sqlite3');
const path = require('path');
const dbPath = path.join(process.cwd(), 'data', 'fitai.db');
const db = new Database(dbPath);
try {
console.log('Attempting to add lastVisit column to clients table...');
db.exec('ALTER TABLE clients ADD COLUMN lastVisit DATETIME');
console.log('Successfully added lastVisit column.');
} catch (error) {
if (error.message.includes('duplicate column name')) {
console.log('Column lastVisit already exists.');
} else {
console.error('Error adding column:', error);
}
}
db.close();
+62
View File
@@ -0,0 +1,62 @@
const Database = require('better-sqlite3');
const path = require('path');
const dbPath = path.join(__dirname, '../data/fitai.db');
const db = new Database(dbPath);
function migrateRoles() {
try {
console.log('Starting migration to update role constraints...');
// 1. Disable foreign keys
db.pragma('foreign_keys = OFF');
// 2. Start transaction
db.transaction(() => {
// 3. Create new table with updated check constraint
console.log('Creating new users table...');
db.prepare(`
CREATE TABLE IF NOT EXISTS users_new (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
firstName TEXT NOT NULL,
lastName TEXT NOT NULL,
password TEXT NOT NULL,
phone TEXT,
role TEXT NOT NULL CHECK (role IN ('superAdmin', 'admin', 'trainer', 'client')),
createdAt DATETIME NOT NULL,
updatedAt DATETIME NOT NULL
)
`).run();
// 4. Copy data
console.log('Copying data...');
db.prepare(`
INSERT INTO users_new (id, email, firstName, lastName, password, phone, role, createdAt, updatedAt)
SELECT id, email, firstName, lastName, password, phone, role, createdAt, updatedAt FROM users
`).run();
// 5. Drop old table
console.log('Dropping old table...');
db.prepare('DROP TABLE users').run();
// 6. Rename new table
console.log('Renaming new table...');
db.prepare('ALTER TABLE users_new RENAME TO users').run();
// 7. Re-enable foreign keys (in a separate step usually, but good to be safe)
})();
db.pragma('foreign_keys = ON');
console.log('Migration completed successfully.');
} catch (error) {
console.error('Migration failed:', error);
process.exit(1);
} finally {
db.close();
}
}
migrateRoles();
+51
View File
@@ -0,0 +1,51 @@
const Database = require('better-sqlite3');
const path = require('path');
const bcrypt = require('bcryptjs');
const dbPath = path.join(__dirname, '../data/fitai.db');
const db = new Database(dbPath);
async function seedSuperAdmin() {
const email = 'taratur@gmail.com';
const password = 'password123';
const firstName = 'Super';
const lastName = 'Admin';
// Hash password
const hashedPassword = await bcrypt.hash(password, 12);
const id = 'user_superadmin_' + Math.random().toString(36).substr(2, 9);
const now = new Date().toISOString();
try {
console.log('Creating Super Admin...');
// Check if exists
const existing = db.prepare('SELECT * FROM users WHERE email = ?').get(email);
if (existing) {
console.log('Super Admin already exists. Updating role...');
db.prepare('UPDATE users SET role = "superAdmin" WHERE email = ?').run(email);
console.log('Role updated.');
return;
}
db.prepare(`
INSERT INTO users (id, email, firstName, lastName, password, role, createdAt, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`).run(id, email, firstName, lastName, hashedPassword, 'superAdmin', now, now);
console.log(`Super Admin created successfully.`);
console.log(`Email: ${email}`);
console.log(`Password: ${password}`);
console.log(`ID: ${id}`);
console.log('\nIMPORTANT: You must also create this user in Clerk manually or sign up with this email to link the accounts if you want to log in as this user.');
} catch (error) {
console.error('Error creating Super Admin:', error);
} finally {
db.close();
}
}
seedSuperAdmin();
@@ -0,0 +1,27 @@
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import { getDatabase } from '@/lib/database'
import { ensureUserSynced } from '@/lib/sync-user'
export async function GET(req: Request) {
try {
const { userId } = await auth()
if (!userId) return new NextResponse('Unauthorized', { status: 401 })
const db = await getDatabase()
// Ensure user is synced (handles seed script ID mismatch)
// We need to import ensureUserSynced
const user = await ensureUserSynced(userId, db)
if (!user || (user.role !== 'admin' && user.role !== 'superAdmin')) {
return new NextResponse('Forbidden', { status: 403 })
}
const attendance = await db.getAllAttendance()
return NextResponse.json(attendance)
} catch (error) {
console.error('Admin attendance error:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
@@ -0,0 +1,25 @@
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import { getDatabase } from '@/lib/database'
import { ensureUserSynced } from '@/lib/sync-user'
export async function GET() {
try {
const { userId } = await auth()
if (!userId) return new NextResponse('Unauthorized', { status: 401 })
const db = await getDatabase()
const user = await ensureUserSynced(userId, db)
if (!user || (user.role !== 'admin' && user.role !== 'superAdmin')) {
return new NextResponse('Forbidden', { status: 403 })
}
const stats = await db.getDashboardStats()
return NextResponse.json(stats)
} catch (error) {
console.error('Dashboard stats error:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
@@ -0,0 +1,31 @@
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import { getDatabase } from '@/lib/database'
import { ensureUserSynced } from '@/lib/sync-user'
export async function POST(req: Request) {
try {
const { userId } = await auth()
if (!userId) return new NextResponse('Unauthorized', { status: 401 })
const db = await getDatabase()
// Ensure user exists in DB (sync from Clerk if needed)
await ensureUserSynced(userId, db)
// Check if already checked in
const activeCheckIn = await db.getActiveCheckIn(userId)
if (activeCheckIn) {
return new NextResponse('Already checked in', { status: 400 })
}
const body = await req.json()
const { type = 'gym', notes } = body
const attendance = await db.checkIn(userId, type, notes)
return NextResponse.json(attendance)
} catch (error) {
console.error('Check-in error:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
@@ -0,0 +1,23 @@
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import { getDatabase } from '@/lib/database'
export async function POST(req: Request) {
try {
const { userId } = await auth()
if (!userId) return new NextResponse('Unauthorized', { status: 401 })
const db = await getDatabase()
const activeCheckIn = await db.getActiveCheckIn(userId)
if (!activeCheckIn) {
return new NextResponse('No active check-in found', { status: 404 })
}
const attendance = await db.checkOut(activeCheckIn.id)
return NextResponse.json(attendance)
} catch (error) {
console.error('Check-out error:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
@@ -0,0 +1,31 @@
import { auth } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'
import { getDatabase } from '@/lib/database'
import { ensureUserSynced } from '@/lib/sync-user'
export async function GET(req: Request) {
console.log('GET /api/attendance/history called')
console.log('Headers:', Object.fromEntries(req.headers.entries()))
try {
const authResult = await auth()
const { userId } = authResult
console.log('Auth result:', JSON.stringify(authResult, null, 2))
if (!userId) {
console.log('No userId found in auth result')
return new NextResponse('Unauthorized', { status: 401 })
}
const db = await getDatabase()
// Ensure user exists in DB (sync from Clerk if needed)
await ensureUserSynced(userId, db)
const history = await db.getAttendanceHistory(userId)
return NextResponse.json(history)
} catch (error) {
console.error('History error:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
@@ -0,0 +1,39 @@
import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@clerk/nextjs/server';
import { getDatabase } from '@/lib/database';
// POST - Mark goal as complete
export async function POST(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
const db = await getDatabase();
// Verify goal exists and user owns it
const existingGoal = await db.getFitnessGoalById(id);
if (!existingGoal) {
return NextResponse.json({ error: 'Goal not found' }, { status: 404 });
}
if (existingGoal.userId !== userId) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
// Mark as completed
const completedGoal = await db.completeGoal(id);
return NextResponse.json(completedGoal);
} catch (error) {
console.error('Error completing fitness goal:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
@@ -0,0 +1,119 @@
import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@clerk/nextjs/server';
import { getDatabase } from '@/lib/database';
// GET - Get specific goal
export async function GET(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
const db = await getDatabase();
const goal = await db.getFitnessGoalById(id);
if (!goal) {
return NextResponse.json({ error: 'Goal not found' }, { status: 404 });
}
// Verify ownership
if (goal.userId !== userId) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
return NextResponse.json(goal);
} catch (error) {
console.error('Error fetching fitness goal:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
// PUT - Update goal
export async function PUT(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
const db = await getDatabase();
// Verify goal exists and user owns it
const existingGoal = await db.getFitnessGoalById(id);
if (!existingGoal) {
return NextResponse.json({ error: 'Goal not found' }, { status: 404 });
}
if (existingGoal.userId !== userId) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
const updates = await req.json();
// Don't allow changing userId or id
delete updates.userId;
delete updates.id;
delete updates.createdAt;
const updatedGoal = await db.updateFitnessGoal(id, updates);
return NextResponse.json(updatedGoal);
} catch (error) {
console.error('Error updating fitness goal:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
// DELETE - Delete goal
export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id } = await params;
const db = await getDatabase();
// Verify goal exists and user owns it
const existingGoal = await db.getFitnessGoalById(id);
if (!existingGoal) {
return NextResponse.json({ error: 'Goal not found' }, { status: 404 });
}
if (existingGoal.userId !== userId) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
const deleted = await db.deleteFitnessGoal(id);
if (deleted) {
return NextResponse.json({ success: true });
} else {
return NextResponse.json({ error: 'Failed to delete goal' }, { status: 500 });
}
} catch (error) {
console.error('Error deleting fitness goal:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
@@ -0,0 +1,95 @@
import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@clerk/nextjs/server';
import { getDatabase } from '@/lib/database';
import { randomBytes } from 'crypto';
// GET - List user's fitness goals
export async function GET(req: NextRequest) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { searchParams } = new URL(req.url);
const targetUserId = searchParams.get('userId') || userId;
const status = searchParams.get('status'); // active, completed, all
const db = await getDatabase();
// Fetch goals with optional status filter
const goals = await db.getFitnessGoalsByUserId(
targetUserId,
status && status !== 'all' ? status : undefined
);
return NextResponse.json(goals);
} catch (error) {
console.error('Error fetching fitness goals:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
// POST - Create new fitness goal
export async function POST(req: NextRequest) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await req.json();
const {
goalType,
title,
description,
targetValue,
currentValue,
unit,
targetDate,
priority,
notes,
fitnessProfileId
} = body;
// Validation
if (!goalType || !title) {
return NextResponse.json(
{ error: 'goalType and title are required' },
{ status: 400 }
);
}
const db = await getDatabase();
// Create the goal
const goal = await db.createFitnessGoal({
id: randomBytes(16).toString('hex'),
userId,
fitnessProfileId: fitnessProfileId || undefined,
goalType,
title,
description: description || undefined,
targetValue: targetValue || undefined,
currentValue: currentValue || 0,
unit: unit || undefined,
startDate: new Date(),
targetDate: targetDate ? new Date(targetDate) : undefined,
status: 'active',
progress: 0,
priority: priority || 'medium',
notes: notes || undefined
});
return NextResponse.json(goal, { status: 201 });
} catch (error) {
console.error('Error creating fitness goal:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
@@ -0,0 +1,151 @@
import { NextRequest, NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server";
import Database from "better-sqlite3";
import { randomBytes } from "crypto";
const db = new Database("./data/fitai.db");
// GET - Fetch fitness profile for the authenticated user
export async function GET(request: NextRequest) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const profile = db
.prepare(
`SELECT * FROM fitness_profiles WHERE userId = ?`
)
.get(userId);
if (profile) {
const p = profile as any;
// Parse JSON fields
try {
p.fitnessGoals = JSON.parse(p.fitnessGoals || '[]');
} catch (e) {
p.fitnessGoals = [];
}
}
return NextResponse.json({ profile: profile || null });
} catch (error) {
console.error("Error fetching fitness profile:", error);
return NextResponse.json(
{ error: "Failed to fetch fitness profile" },
{ status: 500 }
);
}
}
// POST - Create or update fitness profile for the authenticated user
export async function POST(request: NextRequest) {
try {
const { userId } = await auth();
if (!userId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const body = await request.json();
const {
height,
weight,
age,
gender,
fitnessGoals, // Changed from fitnessGoal
activityLevel,
medicalConditions,
allergies,
injuries,
exerciseHabits,
dietHabits
} = body;
// Check if profile exists
const existingProfile = db
.prepare(`SELECT userId FROM fitness_profiles WHERE userId = ?`)
.get(userId) as { userId: string } | undefined;
const now = new Date().toISOString();
const fitnessGoalsJson = JSON.stringify(fitnessGoals || []);
if (existingProfile) {
// Update existing profile
db.prepare(
`UPDATE fitness_profiles
SET height = ?,
weight = ?,
age = ?,
gender = ?,
fitnessGoals = ?,
activityLevel = ?,
medicalConditions = ?,
allergies = ?,
injuries = ?,
exerciseHabits = ?,
dietHabits = ?,
updatedAt = ?
WHERE userId = ?`
).run(
height || null,
weight || null,
age || null,
gender || null,
fitnessGoalsJson,
activityLevel || null,
medicalConditions || null,
allergies || null,
injuries || null,
exerciseHabits || null,
dietHabits || null,
now,
userId
);
return NextResponse.json({
message: "Fitness profile updated successfully",
userId: userId,
});
} else {
// Create new profile
db.prepare(
`INSERT INTO fitness_profiles
(userId, height, weight, age, gender, fitnessGoals, activityLevel,
medicalConditions, allergies, injuries, exerciseHabits, dietHabits, createdAt, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
userId,
height || null,
weight || null,
age || null,
gender || null,
fitnessGoalsJson,
activityLevel || null,
medicalConditions || null,
allergies || null,
injuries || null,
exerciseHabits || null,
dietHabits || null,
now,
now
);
return NextResponse.json(
{
message: "Fitness profile created successfully",
userId,
},
{ status: 201 }
);
}
} catch (error) {
console.error("Error saving fitness profile:", error);
return NextResponse.json(
{ error: "Failed to save fitness profile" },
{ status: 500 }
);
}
}
+5
View File
@@ -0,0 +1,5 @@
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json({ status: 'ok', timestamp: new Date().toISOString() })
}
@@ -0,0 +1,49 @@
import { NextResponse } from "next/server";
import { getDatabase } from "@/lib/database";
export async function POST(req: Request) {
try {
const { recommendationId, status, approvedBy } = await req.json();
if (!recommendationId || !status) {
return NextResponse.json(
{ error: "Recommendation ID and status are required" },
{ status: 400 }
);
}
const db = await getDatabase();
// Update recommendation status
const updates: any = {
status,
approvedAt: status === "approved" ? new Date() : undefined,
approvedBy: status === "approved" ? approvedBy : undefined,
};
// Remove undefined keys
Object.keys(updates).forEach(key => updates[key] === undefined && delete updates[key]);
const updatedRecommendation = await db.updateRecommendation(recommendationId, updates);
if (!updatedRecommendation) {
return NextResponse.json(
{ error: "Recommendation not found" },
{ status: 404 }
);
}
// If approved, create a notification for the user
// Note: IDatabase doesn't have createNotification yet, so we'll skip it for now
// or we need to add it to IDatabase/SQLiteDatabase
// For now, let's assume the notification is handled elsewhere or add it later
return NextResponse.json(updatedRecommendation);
} catch (error) {
console.error("Error approving recommendation:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
@@ -0,0 +1,191 @@
import { NextResponse } from "next/server";
import { getDatabase } from "@/lib/database";
import { buildAIContext } from "@/lib/ai/ai-context";
import { buildEnhancedPrompt, buildBasicPrompt } from "@/lib/ai/prompt-builder";
export async function POST(req: Request) {
try {
const { userId, useExternalModel } = await req.json();
if (!userId) {
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
}
const db = await getDatabase();
// Fetch fitness profile
const profile = await db.getFitnessProfileByUserId(userId);
if (!profile) {
return NextResponse.json(
{ error: "Fitness profile not found for this user" },
{ status: 404 }
);
}
// Build AI context with goals and recommendations
let prompt: string;
try {
const context = await buildAIContext(userId);
prompt = buildEnhancedPrompt(context);
console.log('Using enhanced AI context with goals and history');
} catch (error) {
// Fallback to basic prompt if context building fails
console.warn('Failed to build AI context, using basic prompt:', error);
prompt = buildBasicPrompt(profile);
}
let parsedResponse;
if (useExternalModel) {
// Use DeepSeek AI
const deepseekApiKey = process.env.DEEPSEEK_API_KEY;
if (!deepseekApiKey) {
return NextResponse.json(
{ error: "DeepSeek API key not configured" },
{ status: 500 }
);
}
console.log("Using DeepSeek AI model...");
const deepseekResponse = await fetch("https://api.deepseek.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${deepseekApiKey}`,
},
body: JSON.stringify({
model: "deepseek-chat",
messages: [
{
role: "system",
content: "You are a professional fitness trainer and nutritionist. Always respond with valid JSON only, no markdown or code blocks."
},
{
role: "user",
content: prompt
}
],
temperature: 0.7,
max_tokens: 1000,
}),
});
if (!deepseekResponse.ok) {
const errorText = await deepseekResponse.text();
console.error("DeepSeek API error:", errorText);
return NextResponse.json(
{ error: "Failed to generate recommendation from DeepSeek AI" },
{ status: 500 }
);
}
const deepseekData = await deepseekResponse.json();
console.log("Raw DeepSeek Response:", deepseekData);
try {
const content = deepseekData.choices[0].message.content;
let cleanResponse = content.trim();
// Remove markdown code blocks if present
if (cleanResponse.startsWith("```json")) {
cleanResponse = cleanResponse.replace(/^```json\s*/, "").replace(/\s*```$/, "");
} else if (cleanResponse.startsWith("```")) {
cleanResponse = cleanResponse.replace(/^```\s*/, "").replace(/\s*```$/, "");
}
// Find the first '{' and last '}' to extract the JSON object
const firstBrace = cleanResponse.indexOf("{");
const lastBrace = cleanResponse.lastIndexOf("}");
if (firstBrace !== -1 && lastBrace !== -1) {
cleanResponse = cleanResponse.substring(firstBrace, lastBrace + 1);
}
parsedResponse = JSON.parse(cleanResponse);
} catch (e) {
console.error("Failed to parse DeepSeek response:", deepseekData);
return NextResponse.json(
{ error: "Invalid response format from DeepSeek AI" },
{ status: 500 }
);
}
} else {
// Use local Ollama
console.log("Using local Ollama model...");
const ollamaResponse = await fetch("http://localhost:11434/api/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gemma3:latest",
prompt: prompt,
stream: false,
format: "json",
}),
});
if (!ollamaResponse.ok) {
console.error("Ollama API error:", await ollamaResponse.text());
return NextResponse.json(
{ error: "Failed to generate recommendation from Ollama" },
{ status: 500 }
);
}
const aiData = await ollamaResponse.json();
console.log("Raw Ollama Response:", aiData.response);
try {
let cleanResponse = aiData.response.trim();
// Remove markdown code blocks if present
if (cleanResponse.startsWith("```json")) {
cleanResponse = cleanResponse.replace(/^```json\s*/, "").replace(/\s*```$/, "");
} else if (cleanResponse.startsWith("```")) {
cleanResponse = cleanResponse.replace(/^```\s*/, "").replace(/\s*```$/, "");
}
// Find the first '{' and last '}' to extract the JSON object
const firstBrace = cleanResponse.indexOf("{");
const lastBrace = cleanResponse.lastIndexOf("}");
if (firstBrace !== -1 && lastBrace !== -1) {
cleanResponse = cleanResponse.substring(firstBrace, lastBrace + 1);
}
parsedResponse = JSON.parse(cleanResponse);
} catch (e) {
console.error("Failed to parse Ollama response:", aiData.response);
return NextResponse.json(
{ error: "Invalid response format from Ollama" },
{ status: 500 }
);
}
}
// Save to database
const recommendation = await db.createRecommendation({
id: crypto.randomUUID(),
userId,
fitnessProfileId: profile.userId,
type: 'ai_plan',
content: parsedResponse.recommendationText,
activityPlan: parsedResponse.activityPlan,
dietPlan: parsedResponse.dietPlan,
status: 'pending'
});
return NextResponse.json(recommendation);
} catch (error) {
console.error("Error generating recommendation:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
@@ -0,0 +1,136 @@
import { NextResponse } from 'next/server'
import { auth } from '@clerk/nextjs/server'
import { getDatabase } from '@/lib/database'
export async function GET(request: Request) {
try {
const { userId: currentUserId } = await auth()
if (!currentUserId) {
return new NextResponse('Unauthorized', { status: 401 })
}
const { searchParams } = new URL(request.url)
const targetUserId = searchParams.get('userId')
const db = await getDatabase()
// If no userId provided, check if staff and return all recommendations
if (!targetUserId) {
const currentUser = await db.getUserById(currentUserId)
const isStaff = currentUser?.role === 'admin' || currentUser?.role === 'superAdmin' || currentUser?.role === 'trainer'
if (!isStaff) {
return new NextResponse('User ID is required', { status: 400 })
}
const recommendations = await db.getAllRecommendations()
return NextResponse.json({ recommendations })
}
// Check permissions: Users can view their own, Admins/Trainers can view anyone's
const currentUser = await db.getUserById(currentUserId)
const isStaff = currentUser?.role === 'admin' || currentUser?.role === 'superAdmin' || currentUser?.role === 'trainer'
if (currentUserId !== targetUserId) {
if (!isStaff) {
return new NextResponse('Forbidden', { status: 403 })
}
}
let recommendations = await db.getRecommendationsByUserId(targetUserId)
// Non-staff users should only see approved recommendations
if (!isStaff) {
recommendations = recommendations.filter((rec: any) => rec.status === 'approved')
}
return NextResponse.json(recommendations)
} catch (error) {
console.error('Error fetching recommendations:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
export async function POST(request: Request) {
try {
const { userId: currentUserId } = await auth()
if (!currentUserId) {
return new NextResponse('Unauthorized', { status: 401 })
}
const db = await getDatabase()
const currentUser = await db.getUserById(currentUserId)
const isStaff = currentUser?.role === 'admin' || currentUser?.role === 'superAdmin' || currentUser?.role === 'trainer'
if (!isStaff) {
return new NextResponse('Forbidden', { status: 403 })
}
const body = await request.json()
const { userId, fitnessProfileId, recommendationText, activityPlan, dietPlan, status, type, content } = body
// Handle AI Plan (Legacy/Specific)
if (recommendationText && activityPlan && dietPlan && fitnessProfileId) {
const recommendation = await db.createRecommendation({
id: crypto.randomUUID(),
userId,
fitnessProfileId,
type: 'ai_plan',
content: recommendationText,
activityPlan,
dietPlan,
status: status || 'pending'
})
return NextResponse.json(recommendation)
}
// Handle User Goal (Generic)
if (type && content) {
const recommendation = await db.createRecommendation({
id: crypto.randomUUID(),
userId,
type,
content,
status: status || 'pending'
})
return NextResponse.json(recommendation)
}
return NextResponse.json('Missing required fields', { status: 400 })
} catch (error) {
console.error('Error creating recommendation:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
export async function PUT(request: Request) {
try {
const { userId: currentUserId } = await auth()
if (!currentUserId) {
return new NextResponse('Unauthorized', { status: 401 })
}
const body = await request.json()
const { id, status, recommendationText, activityPlan, dietPlan, content } = body
if (!id) {
return new NextResponse('Recommendation ID is required', { status: 400 })
}
const db = await getDatabase()
const updated = await db.updateRecommendation(id, {
...(status && { status }),
...(recommendationText && { content: recommendationText }), // Map legacy field
...(content && { content }),
...(activityPlan && { activityPlan }),
...(dietPlan && { dietPlan })
})
return NextResponse.json(updated)
} catch (error) {
console.error('Error updating recommendation:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
}
+136 -12
View File
@@ -1,6 +1,7 @@
import { NextRequest, NextResponse } from "next/server";
import { getDatabase } from "../../../lib/database/index";
import bcrypt from "bcryptjs";
import { auth, clerkClient } from "@clerk/nextjs/server";
export async function GET(request: NextRequest) {
try {
@@ -18,7 +19,52 @@ export async function GET(request: NextRequest) {
users.map(async (user) => {
const { password: _, ...userWithoutPassword } = user;
const client = await db.getClientByUserId(user.id);
return { ...userWithoutPassword, client };
// Get active check-in status and statistics for ALL users
let isCheckedIn = false;
let checkInTime = null;
let lastCheckInTime = null;
let checkInsThisWeek = 0;
let checkInsThisMonth = 0;
// Query attendance by userId (works for all user types now)
const activeCheckIn = await db.getActiveCheckIn(user.id);
if (activeCheckIn) {
isCheckedIn = true;
checkInTime = activeCheckIn.checkInTime;
}
// Get attendance history for statistics
const attendanceHistory = await db.getAttendanceHistory(user.id);
if (attendanceHistory.length > 0) {
// Last check-in is the most recent attendance record
lastCheckInTime = attendanceHistory[0].checkInTime;
// Calculate check-ins in last 7 days
const weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
checkInsThisWeek = attendanceHistory.filter(
a => new Date(a.checkInTime) >= weekAgo
).length;
// Calculate check-ins in last 30 days
const monthAgo = new Date();
monthAgo.setDate(monthAgo.getDate() - 30);
checkInsThisMonth = attendanceHistory.filter(
a => new Date(a.checkInTime) >= monthAgo
).length;
}
return {
...userWithoutPassword,
client,
isCheckedIn,
checkInTime,
lastCheckInTime,
checkInsThisWeek,
checkInsThisMonth
};
}),
);
@@ -34,18 +80,61 @@ export async function GET(request: NextRequest) {
export async function POST(request: NextRequest) {
try {
const db = await getDatabase();
const body = await request.json();
const { email, password, firstName, lastName, role, phone } = body;
const { userId: clerkUserId } = await auth();
if (!clerkUserId) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
if (!email || !password || !firstName || !lastName || !role) {
const db = await getDatabase();
// Get current user to check role
// Note: In a real app, we'd map Clerk ID to our DB ID.
// For now, we'll assume we can find the user by some means or trust the Clerk metadata if we synced it.
// Since we don't have Clerk ID in our local DB users table yet (we only have our own ID),
// we might need to rely on the user being synced.
// Let's assume the user calling this API is already in our DB.
// For the prototype, we'll fetch the user by matching the Clerk ID if we stored it,
// OR we'll assume the first user is Super Admin if no users exist?
// Actually, we should look up the user by email if we can't by ID, or add a clerkId column.
// For this step, let's assume we can get the user.
// WAIT: The current `users` table has `id` as a string. Is it the Clerk ID?
// In `sync-user.ts`, we use `evt.data.id` as the `id` when creating the user.
// So yes, `users.id` IS the Clerk ID.
const currentUser = await db.getUserById(clerkUserId);
if (!currentUser) {
return NextResponse.json({ error: "Current user not found in database" }, { status: 403 });
}
const body = await request.json();
const { email, firstName, lastName, role, phone } = body;
if (!email || !firstName || !lastName || !role) {
return NextResponse.json(
{ error: "Missing required fields" },
{ status: 400 },
);
}
// Check if user already exists
// Enforce Hierarchy
const allowed: Record<string, string[]> = {
superAdmin: ["admin", "trainer", "client"],
admin: ["trainer", "client"],
trainer: ["client"],
client: []
};
const userRole = currentUser.role as keyof typeof allowed;
if (!allowed[userRole] || !allowed[userRole].includes(role)) {
return NextResponse.json(
{ error: `You are not authorized to create a ${role}` },
{ status: 403 }
);
}
// Check if user already exists locally
const existingUser = await db.getUserByEmail(email);
if (existingUser) {
return NextResponse.json(
@@ -54,20 +143,55 @@ export async function POST(request: NextRequest) {
);
}
// Hash password
const hashedPassword = await bcrypt.hash(password, 12);
// Create Clerk Invitation
// Note: We pass the role in publicMetadata so it persists when they sign up
try {
const client = await clerkClient();
await client.invitations.createInvitation({
emailAddress: email,
publicMetadata: {
role,
},
ignoreExisting: true // Don't fail if invite exists
});
} catch (clerkError: any) {
console.error("Clerk invitation error:", clerkError);
// If user already exists in Clerk, we might want to handle it.
// But for now, let's proceed to create local record if invite sent or if they exist.
if (clerkError.errors?.[0]?.code === 'form_identifier_exists') {
return NextResponse.json(
{ error: "User already exists in Clerk system" },
{ status: 409 },
);
}
return NextResponse.json(
{ error: "Failed to send invitation: " + (clerkError.message || "Unknown error") },
{ status: 500 },
);
}
// Create user
const userId = await db.createUser({
// Create user in local DB with temporary ID (will be migrated on first login)
// We set a placeholder password since it's required by schema but won't be used
const newUserId = await db.createUser({
email,
password: hashedPassword,
password: "INVITED_USER_PENDING",
firstName,
lastName,
role,
phone,
});
return NextResponse.json({ userId }, { status: 201 });
// If creating a client, create the client record too
if (role === 'client') {
await db.createClient({
userId: newUserId.id,
membershipType: 'basic',
membershipStatus: 'active',
joinDate: new Date()
});
}
return NextResponse.json({ userId: newUserId.id, message: "Invitation sent" }, { status: 201 });
} catch (error) {
console.error("Create user error:", error);
return NextResponse.json(
+96
View File
@@ -0,0 +1,96 @@
'use client'
import { useState, useEffect } from 'react'
import { format } from 'date-fns'
interface Attendance {
id: string
clientId: string
checkInTime: string
checkOutTime?: string
type: string
notes?: string
}
export default function AttendancePage() {
const [attendance, setAttendance] = useState<Attendance[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
const fetchAttendance = async () => {
try {
const res = await fetch('/api/admin/attendance')
if (res.ok) {
const data = await res.json()
setAttendance(data)
}
} catch (error) {
console.error('Error fetching attendance:', error)
} finally {
setLoading(false)
}
}
fetchAttendance()
}, [])
if (loading) {
return <div className="p-8">Loading...</div>
}
return (
<div className="p-8">
<h1 className="text-2xl font-bold mb-6">Attendance Monitoring</h1>
<div className="bg-white rounded-lg shadow overflow-hidden">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Client ID
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Type
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Check In
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Check Out
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Status
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{attendance.map((record) => (
<tr key={record.id}>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{record.clientId}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 capitalize">
{record.type}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{format(new Date(record.checkInTime), 'PP p')}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{record.checkOutTime ? format(new Date(record.checkOutTime), 'PP p') : '-'}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${record.checkOutTime
? 'bg-gray-100 text-gray-800'
: 'bg-green-100 text-green-800'
}`}>
{record.checkOutTime ? 'Completed' : 'Active'}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)
}
+74 -1
View File
@@ -1,3 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.75rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
+29 -19
View File
@@ -8,6 +8,7 @@ import {
SignInButton,
UserButton,
} from "@clerk/nextjs";
import { Sidebar } from "@/components/ui/Sidebar";
const inter = Inter({ subsets: ["latin"] });
@@ -24,27 +25,36 @@ export default function RootLayout({
return (
<ClerkProvider>
<html lang="en">
<body className={inter.className}>
<header className="bg-white shadow-sm border-b">
<div className="container mx-auto px-4 py-4 flex justify-between items-center">
<div className="flex items-center gap-2">
<h1 className="text-xl font-bold text-gray-900">FitAI Admin</h1>
<body className={`${inter.className} bg-gradient-to-br from-slate-50 via-blue-50 to-slate-100 min-h-screen`}>
<div className="flex min-h-screen">
<Sidebar />
<main className="flex-1 ml-64">
<div className="sticky top-0 z-40 backdrop-blur-xl bg-white/75 border-b border-slate-200/50 shadow-sm">
<div className="px-8 py-4 flex items-center justify-between max-w-7xl mx-auto">
<div>
<h1 className="text-sm font-semibold text-gray-600 uppercase tracking-wide">FitAI Pro</h1>
</div>
<div className="flex items-center gap-4">
<SignedIn>
<UserButton
appearance={{
elements: {
avatarBox: "w-10 h-10 rounded-full ring-2 ring-blue-200"
}
}}
/>
</SignedIn>
<SignedOut>
<SignInButton mode="modal" />
</SignedOut>
</div>
</div>
</div>
<div className="flex items-center gap-4">
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
<SignedOut>
<SignInButton mode="modal">
<button className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors">
Sign In
</button>
</SignInButton>
</SignedOut>
<div className="p-8">
{children}
</div>
</div>
</header>
{children}
</main>
</div>
</body>
</html>
</ClerkProvider>
+111 -47
View File
@@ -1,68 +1,132 @@
"use client";
import Link from "next/link";
import { useEffect, useState } from "react";
import { Users, CreditCard, CalendarCheck, TrendingUp } from "lucide-react";
import { StatsCard } from "@/components/ui/StatsCard";
import { UserManagement } from "@/components/users/UserManagement";
import { AnalyticsDashboard } from "@/components/analytics/AnalyticsDashboard";
import axios from "axios";
interface DashboardStats {
totalUsers: number;
activeClients: number;
totalRevenue: number;
revenueGrowth: number;
}
export default function Home() {
const [stats, setStats] = useState<DashboardStats>({
totalUsers: 0,
activeClients: 0,
totalRevenue: 0,
revenueGrowth: 0,
});
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchStats = async () => {
try {
const response = await axios.get("/api/admin/stats");
setStats(response.data);
} catch (error) {
console.error("Failed to fetch dashboard stats:", error);
} finally {
setLoading(false);
}
};
fetchStats();
}, []);
const formatCurrency = (value: number) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(value);
};
return (
<main className="min-h-screen bg-gray-50">
<div className="container mx-auto px-4 py-8">
<div className="flex justify-between items-center mb-8">
<h1 className="text-4xl font-bold text-gray-900">
FitAI Admin Dashboard
</h1>
<nav className="flex gap-4">
<Link
href="/users"
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
User Management
</Link>
<Link
href="/analytics"
className="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors"
>
Analytics
</Link>
</nav>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold mb-4">Client Management</h2>
<p className="text-gray-600">
Manage fitness clients and their profiles
</p>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold mb-4">Payment Tracking</h2>
<p className="text-gray-600">Monitor payments and subscriptions</p>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-xl font-semibold mb-4">Attendance</h2>
<p className="text-gray-600">Track client attendance and habits</p>
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-100">
<div className="space-y-8 max-w-7xl">
{/* Hero Section */}
<div className="pt-8 pb-4">
<div className="space-y-3">
<div className="flex items-center gap-4">
<img
src="/nextform-logo.png"
alt="NextForm"
className="h-20 w-20 object-contain"
/>
<div className="flex items-center gap-3">
<div className="h-12 w-1 bg-gradient-to-b from-blue-600 to-cyan-600 rounded-full"></div>
<h1 className="text-5xl font-black bg-gradient-to-r from-blue-600 via-blue-700 to-cyan-600 bg-clip-text text-transparent">
NextForm
</h1>
</div>
</div>
<p className="text-lg text-gray-600 ml-4">Performance metrics & athlete insights</p>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-semibold mb-6">
Recent User Activity
</h2>
<div>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-5">
<StatsCard
title="Total Users"
value={loading ? "..." : stats.totalUsers}
change="+12%" // Placeholder for now as we don't track historical growth yet
trend="up"
icon={Users}
color="blue"
/>
<StatsCard
title="Active Clients"
value={loading ? "..." : stats.activeClients}
change="+5%"
trend="up"
icon={CalendarCheck}
color="green"
/>
<StatsCard
title="Revenue"
value={loading ? "..." : formatCurrency(stats.totalRevenue)}
change={`${stats.revenueGrowth > 0 ? "+" : ""}${stats.revenueGrowth}%`}
trend={stats.revenueGrowth >= 0 ? "up" : "down"}
icon={CreditCard}
color="purple"
/>
<StatsCard
title="Growth"
value="24%" // Placeholder
change="-2%"
trend="down"
icon={TrendingUp}
color="orange"
/>
</div>
{/* Main Content Grid */}
<div className="space-y-6 pb-12">
{/* User Management - Full Width */}
<div className="bg-gradient-to-br from-slate-50 via-blue-50/30 to-slate-50 rounded-2xl shadow-lg border border-slate-200/50 p-7 hover:shadow-2xl transition-all duration-300 backdrop-blur-sm">
<div className="space-y-6">
<div>
<h2 className="text-2xl font-bold text-slate-900">Active Athletes</h2>
<p className="text-sm text-gray-500 mt-1">Manage and monitor your fitness clients</p>
</div>
<UserManagement />
</div>
</div>
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-2xl font-semibold mb-6">Quick Analytics</h2>
{/* Analytics - 3 Columns Horizontal Layout */}
<div className="space-y-4">
<div>
<AnalyticsDashboard />
<h2 className="text-2xl font-bold text-slate-900">Analytics</h2>
<p className="text-sm text-gray-500 mt-1">Performance metrics and insights</p>
</div>
<AnalyticsDashboard />
</div>
</div>
</div>
</main>
</div>
);
}
+1 -1
View File
@@ -55,7 +55,7 @@ export default function ProfilePage() {
<div className="flex justify-between items-center mb-6">
<h1 className="text-2xl font-bold">Profile</h1>
<Button
variant={isEditing ? "default" : "outline"}
variant={isEditing ? "primary" : "secondary"}
onClick={() => setIsEditing(!isEditing)}
>
{isEditing ? "Cancel" : "Edit Profile"}
+260
View File
@@ -0,0 +1,260 @@
"use client";
import { useEffect, useState } from "react";
import { useUser } from "@clerk/nextjs";
interface User {
id: string;
firstName: string;
lastName: string;
email: string;
}
interface Recommendation {
id: string;
userId: string;
content: string;
activityPlan: string;
dietPlan: string;
status: string;
createdAt: Date;
}
export default function RecommendationsPage() {
const { user } = useUser();
const [users, setUsers] = useState<User[]>([]);
const [pendingRecommendations, setPendingRecommendations] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
const [generating, setGenerating] = useState<string | null>(null);
const [useExternalModel, setUseExternalModel] = useState(false);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
// Fetch users
const usersRes = await fetch("/api/users");
const usersData = await usersRes.json();
setUsers(usersData.users || []);
// Fetch pending recommendations
const recsRes = await fetch("/api/recommendations");
const recsData = await recsRes.json();
const allRecs = recsData.recommendations || [];
setPendingRecommendations(allRecs.filter((r: any) => r.status === 'pending'));
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setLoading(false);
}
};
const handleGenerate = async (userId: string) => {
setGenerating(userId);
try {
const res = await fetch("/api/recommendations/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId, useExternalModel }),
});
if (!res.ok) {
const error = await res.json();
alert(`Error: ${error.error}`);
} else {
alert("Recommendation generated successfully!");
fetchData(); // Refresh data
}
} catch (error) {
console.error(error);
alert("Failed to generate recommendation.");
} finally {
setGenerating(null);
}
};
const handleApprove = async (recommendationId: string, status: "approved" | "rejected") => {
try {
const res = await fetch("/api/recommendations/approve", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
recommendationId,
status,
approvedBy: user?.id || "admin",
}),
});
if (!res.ok) {
const errorData = await res.json();
alert(`Failed to update status: ${errorData.error || 'Unknown error'}`);
} else {
fetchData(); // Refresh data
}
} catch (error) {
console.error(error);
alert("Error processing request");
}
};
const handleEdit = async (rec: Recommendation) => {
const newContent = prompt("Edit Advice:", rec.content);
const newActivityPlan = prompt("Edit Activity Plan:", rec.activityPlan);
const newDietPlan = prompt("Edit Diet Plan:", rec.dietPlan);
if (newContent === null || newActivityPlan === null || newDietPlan === null) {
// User cancelled one of the prompts
return;
}
try {
const res = await fetch("/api/recommendations", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: rec.id,
content: newContent,
activityPlan: newActivityPlan,
dietPlan: newDietPlan,
}),
});
if (!res.ok) {
const errorData = await res.json();
alert(`Failed to update recommendation: ${errorData.error || 'Unknown error'}`);
} else {
alert("Recommendation updated successfully!");
fetchData(); // Refresh data
}
} catch (error) {
console.error("Error updating recommendation:", error);
alert("Failed to update recommendation.");
}
};
if (loading) {
return (
<div className="flex items-center justify-center h-screen">
<div className="text-xl">Loading...</div>
</div>
);
}
return (
<div className="container mx-auto py-10 px-4">
<div className="flex justify-between items-center mb-8">
<h1 className="text-3xl font-bold">AI Recommendations</h1>
{/* Model Selection Toggle */}
<div className="flex items-center gap-3 bg-white px-4 py-2 rounded-lg shadow">
<span className="text-sm font-medium text-gray-700">
{useExternalModel ? "DeepSeek AI" : "Local Ollama"}
</span>
<button
onClick={() => setUseExternalModel(!useExternalModel)}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${useExternalModel ? "bg-blue-600" : "bg-gray-300"
}`}
>
<span
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${useExternalModel ? "translate-x-6" : "translate-x-1"
}`}
/>
</button>
<span className="text-xs text-gray-500">
{useExternalModel ? "External" : "Local"}
</span>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Generate Section */}
<div>
<h2 className="text-2xl font-semibold mb-4">Generate Recommendations</h2>
<div className="bg-white shadow rounded-lg p-6">
<p className="mb-4 text-gray-600">
Select a user to generate a new daily recommendation.
</p>
<ul className="space-y-4">
{users.map((user) => (
<li key={user.id} className="flex items-center justify-between border-b pb-2">
<div>
<p className="font-medium">
{user.firstName} {user.lastName}
</p>
<p className="text-sm text-gray-500">{user.email}</p>
</div>
<button
onClick={() => handleGenerate(user.id)}
disabled={generating === user.id}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50"
>
{generating === user.id ? "Generating..." : "Generate"}
</button>
</li>
))}
{users.length === 0 && (
<p className="text-gray-500 italic">No users found.</p>
)}
</ul>
</div>
</div>
{/* Pending Approvals Section */}
<div>
<h2 className="text-2xl font-semibold mb-4">Pending Approvals</h2>
<div className="bg-white shadow rounded-lg p-6">
{pendingRecommendations.length === 0 ? (
<p className="text-gray-500 italic">No pending recommendations.</p>
) : (
<ul className="space-y-6">
{pendingRecommendations.map((rec) => (
<li key={rec.id} className="border rounded p-4">
<div className="flex justify-between items-start mb-2">
<h3 className="font-bold">For: User {rec.userId}</h3>
<span className="text-xs text-gray-500">
{new Date(rec.createdAt).toLocaleDateString()}
</span>
</div>
<div className="space-y-2 text-sm mb-4">
<div>
<span className="font-semibold">Advice:</span> {rec.content}
</div>
<div>
<span className="font-semibold">Activity:</span> {rec.activityPlan}
</div>
<div>
<span className="font-semibold">Diet:</span> {rec.dietPlan}
</div>
</div>
<div className="flex space-x-2">
<button
onClick={() => handleEdit(rec)}
className="flex-1 bg-blue-500 text-white py-2 rounded hover:bg-blue-600"
>
Edit
</button>
<button
onClick={() => handleApprove(rec.id, "approved")}
className="flex-1 bg-green-600 text-white py-2 rounded hover:bg-green-700"
>
Approve
</button>
<button
onClick={() => handleApprove(rec.id, "rejected")}
className="flex-1 bg-red-600 text-white py-2 rounded hover:bg-red-700"
>
Reject
</button>
</div>
</li>
))}
</ul>
)}
</div>
</div>
</div>
</div>
);
}
+104
View File
@@ -0,0 +1,104 @@
import { getDatabase } from "@/lib/database";
import { Recommendations } from "@/components/users/Recommendations";
import { notFound } from "next/navigation";
interface PageProps {
params: Promise<{
id: string;
}>;
}
export default async function UserProfilePage({ params }: PageProps) {
const { id } = await params;
const db = await getDatabase();
const user = await db.getUserById(id);
if (!user) {
notFound();
}
const client = await db.getClientByUserId(user.id);
const fitnessProfile = await db.getFitnessProfileByUserId(user.id);
return (
<div className="space-y-8">
<div className="flex justify-between items-center">
<h1 className="text-3xl font-bold">
{user.firstName} {user.lastName}
</h1>
<span className="px-3 py-1 bg-gray-100 rounded-full text-sm font-medium capitalize">
{user.role}
</span>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Basic Info */}
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Contact Information</h2>
<div className="space-y-2">
<p><span className="font-medium">Email:</span> {user.email}</p>
<p><span className="font-medium">Phone:</span> {user.phone || "N/A"}</p>
<p><span className="font-medium">Joined:</span> {user.createdAt.toLocaleDateString()}</p>
</div>
</div>
{/* Client Info */}
{client && (
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Membership Details</h2>
<div className="space-y-2">
<p><span className="font-medium">Type:</span> {client.membershipType}</p>
<p><span className="font-medium">Status:</span> {client.membershipStatus}</p>
<p><span className="font-medium">Member Since:</span> {client.joinDate.toLocaleDateString()}</p>
<p><span className="font-medium">Last Visit:</span> {client.lastVisit?.toLocaleDateString() || "Never"}</p>
</div>
</div>
)}
</div>
{/* Fitness Profile */}
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Fitness Profile</h2>
{fitnessProfile ? (
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div>
<h3 className="font-medium mb-2 text-gray-700">Physical Stats</h3>
<p>Height: {fitnessProfile.height} cm</p>
<p>Weight: {fitnessProfile.weight} kg</p>
<p>Age: {fitnessProfile.age}</p>
<p>Gender: {fitnessProfile.gender}</p>
</div>
<div>
<h3 className="font-medium mb-2 text-gray-700">Health & Habits</h3>
<p>Activity Level: {fitnessProfile.activityLevel.replace('_', ' ')}</p>
<p>Diet: {fitnessProfile.dietHabits || "N/A"}</p>
<p>Exercise: {fitnessProfile.exerciseHabits || "N/A"}</p>
</div>
<div>
<h3 className="font-medium mb-2 text-gray-700">Medical</h3>
<p>Conditions: {fitnessProfile.medicalConditions || "None"}</p>
<p>Allergies: {fitnessProfile.allergies || "None"}</p>
<p>Injuries: {fitnessProfile.injuries || "None"}</p>
</div>
<div className="col-span-full mt-4">
<h3 className="font-medium mb-2 text-gray-700">Goals</h3>
<div className="flex flex-wrap gap-2">
{fitnessProfile.fitnessGoals.map((goal, i) => (
<span key={i} className="px-2 py-1 bg-blue-50 text-blue-700 rounded text-sm">
{goal.replace('_', ' ')}
</span>
))}
</div>
</div>
</div>
) : (
<p className="text-gray-500 italic">No fitness profile created yet.</p>
)}
</div>
{/* Recommendations Component */}
<Recommendations userId={user.id} />
</div>
);
}
+26 -16
View File
@@ -3,7 +3,7 @@
import { type ReactElement } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Home, Users, BarChart3, User } from "lucide-react";
import { Home, Users, BarChart3, User, Brain } from "lucide-react";
import { SignedIn, UserButton } from "@clerk/nextjs";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
@@ -25,6 +25,11 @@ const navItems: NavItem[] = [
label: "Clients",
icon: Users,
},
{
href: "/recommendations",
label: "AI Recommendations",
icon: Brain,
},
{
href: "/analytics",
label: "Analytics",
@@ -47,9 +52,16 @@ export function Navigation(): ReactElement {
{/* Logo */}
<Link
href="/"
className="text-xl font-bold text-[#FF0000] hover:text-[#00FF00] transition-colors"
className="flex items-center gap-3 hover:opacity-80 transition-opacity"
>
FitAI
<img
src="/nextform-logo.png"
alt="NextForm"
className="h-10 w-10 object-contain"
/>
<span className="text-lg font-bold bg-gradient-to-r from-blue-600 to-blue-800 bg-clip-text text-transparent">
NextForm
</span>
</Link>
{/* Navigation Items */}
@@ -59,22 +71,20 @@ export function Navigation(): ReactElement {
>
{navItems.map((item) => (
<li key={item.href}>
<Button
asChild
variant={pathname === item.href ? "default" : "ghost"}
size="sm"
className={cn(
"h-9 px-4 py-2",
pathname === item.href &&
<Link href={item.href} className="flex items-center gap-2">
<Button
variant={pathname === item.href ? "primary" : "secondary"}
className={cn(
"h-9 px-4 py-2",
pathname === item.href &&
"bg-primary text-primary-foreground",
)}
aria-current={pathname === item.href ? "page" : undefined}
>
<Link href={item.href} className="flex items-center gap-2">
)}
aria-current={pathname === item.href ? "page" : undefined}
>
<item.icon className="h-4 w-4" />
<span>{item.label}</span>
</Link>
</Button>
</Button>
</Link>
</li>
))}
</ul>
@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react'
import { UserGrowthChart } from '@/components/charts/UserGrowthChart'
import { MembershipDistributionChart } from '@/components/charts/MembershipDistributionChart'
import { RevenueChart } from '@/components/charts/RevenueChart'
import { Card, CardHeader, CardContent } from '@/components/ui/Card'
import { Card, CardHeader, CardContent } from '@/components/ui/card'
interface ChartData {
label: string
@@ -67,74 +67,75 @@ export function AnalyticsDashboard() {
if (loading) {
return (
<div className="flex justify-center items-center h-64">
<div className="text-lg">Loading analytics...</div>
<div className="text-center">
<div className="inline-block animate-spin">⚡</div>
<p className="text-gray-600 mt-2 text-sm">Loading analytics...</p>
</div>
</div>
)
}
return (
<div className="space-y-6">
<h2 className="text-2xl font-bold">Analytics Dashboard</h2>
<div className="space-y-4">
{/* Key Metrics Cards - 3 columns */}
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div className="bg-gradient-to-br from-blue-700 via-cyan-500 to-blue-600 rounded-xl p-5 border-0 shadow-lg hover:shadow-2xl transition-all text-white">
<p className="text-xs uppercase tracking-wide font-bold text-white mb-2">Total Athletes</p>
<div className="flex items-baseline gap-2">
<div className="text-2xl font-black text-white">{totalUsers}</div>
<span className="text-xs text-white font-semibold">active</span>
</div>
</div>
{/* Key Metrics */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card>
<CardContent>
<div className="text-center">
<div className="text-3xl font-bold text-blue-600">{totalUsers}</div>
<div className="text-gray-600">Total Users</div>
</div>
</CardContent>
</Card>
<Card>
<CardContent>
<div className="text-center">
<div className="text-3xl font-bold text-green-600">${totalRevenue.toLocaleString()}</div>
<div className="text-gray-600">Total Revenue</div>
</div>
</CardContent>
</Card>
<Card>
<CardContent>
<div className="text-center">
<div className="text-3xl font-bold text-purple-600">{activeMembers}</div>
<div className="text-gray-600">Active Members</div>
</div>
</CardContent>
</Card>
<div className="bg-gradient-to-br from-amber-700 via-yellow-500 to-amber-600 rounded-xl p-5 border-0 shadow-lg hover:shadow-2xl transition-all text-white">
<p className="text-xs uppercase tracking-wide font-bold text-white mb-2">Total Revenue</p>
<div className="flex items-baseline gap-2">
<div className="text-2xl font-black text-white">${totalRevenue.toLocaleString()}</div>
<span className="text-xs text-white font-semibold">ytd</span>
</div>
</div>
<div className="bg-gradient-to-br from-pink-700 via-fuchsia-500 to-pink-600 rounded-xl p-5 border-0 shadow-lg hover:shadow-2xl transition-all text-white">
<p className="text-xs uppercase tracking-wide font-bold text-white mb-2">Active Members</p>
<div className="flex items-baseline gap-2">
<div className="text-2xl font-black text-white">{activeMembers}</div>
<span className="text-xs text-white font-semibold">members</span>
</div>
</div>
</div>
{/* Charts */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<Card>
<CardHeader>
<h3 className="text-lg font-semibold">User Growth</h3>
</CardHeader>
<CardContent>
{/* Charts - 3 Columns Horizontal */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
<div className="bg-gradient-to-br from-blue-700 via-cyan-500 to-blue-600 rounded-xl shadow-lg border-0 p-5 hover:shadow-2xl transition-all">
<div className="mb-3">
<h3 className="text-sm font-bold text-white">User Growth Trend</h3>
<p className="text-xs text-blue-100">Last 6 months performance</p>
</div>
<div className="h-48 overflow-auto">
<UserGrowthChart data={userGrowthData} />
</CardContent>
</Card>
</div>
</div>
<Card>
<CardHeader>
<h3 className="text-lg font-semibold">Membership Distribution</h3>
</CardHeader>
<CardContent>
<div className="bg-gradient-to-br from-amber-700 via-yellow-500 to-amber-600 rounded-xl shadow-lg border-0 p-5 hover:shadow-2xl transition-all">
<div className="mb-3">
<h3 className="text-sm font-bold text-white">Membership Mix</h3>
<p className="text-xs text-amber-100">Distribution breakdown</p>
</div>
<div className="h-48 overflow-auto">
<MembershipDistributionChart data={membershipData} />
</CardContent>
</Card>
</div>
</div>
</div>
<Card>
<CardHeader>
<h3 className="text-lg font-semibold">Monthly Revenue</h3>
</CardHeader>
<CardContent>
<RevenueChart data={revenueData} />
</CardContent>
</Card>
<div className="bg-gradient-to-br from-pink-700 via-fuchsia-500 to-pink-600 rounded-xl shadow-lg border-0 p-5 hover:shadow-2xl transition-all">
<div className="mb-3">
<h3 className="text-sm font-bold text-white">Revenue Stream</h3>
<p className="text-xs text-pink-100">Monthly earnings</p>
</div>
<div className="h-48 overflow-auto">
<RevenueChart data={revenueData} />
</div>
</div>
</div>
</div>
)
}
@@ -0,0 +1,44 @@
"use client";
import { useState } from "react";
import { Loader2 } from "lucide-react";
export function GenerateButton({ userId }: { userId: string }) {
const [loading, setLoading] = useState(false);
const handleGenerate = async () => {
setLoading(true);
try {
const res = await fetch("/api/recommendations/generate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId }),
});
if (!res.ok) {
const error = await res.json();
alert(`Error: ${error.error}`);
} else {
alert("Recommendation generated successfully! Check Pending Approvals.");
// In a real app, we'd revalidate the path or update state
window.location.reload();
}
} catch (error) {
console.error(error);
alert("Failed to generate recommendation.");
} finally {
setLoading(false);
}
};
return (
<button
onClick={handleGenerate}
disabled={loading}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50 flex items-center"
>
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Generate
</button>
);
}
@@ -0,0 +1,117 @@
"use client";
import { useState } from "react";
import { Loader2, Check, X } from "lucide-react";
type Recommendation = {
recommendation: {
id: string;
recommendationText: string;
activityPlan: string;
dietPlan: string;
createdAt: Date;
};
user: {
firstName: string;
lastName: string;
};
};
export function RecommendationList({
initialRecommendations,
}: {
initialRecommendations: Recommendation[];
}) {
const [recommendations, setRecommendations] = useState(initialRecommendations);
const [processingId, setProcessingId] = useState<string | null>(null);
const handleAction = async (id: string, status: "approved" | "rejected") => {
setProcessingId(id);
try {
const res = await fetch("/api/recommendations/approve", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
recommendationId: id,
status,
approvedBy: "admin_placeholder", // In real app, get from auth context
}),
});
if (!res.ok) {
alert("Failed to update status");
} else {
setRecommendations((prev) =>
prev.filter((item) => item.recommendation.id !== id)
);
}
} catch (error) {
console.error(error);
alert("Error processing request");
} finally {
setProcessingId(null);
}
};
if (recommendations.length === 0) {
return <p className="text-gray-500 italic">No pending recommendations.</p>;
}
return (
<ul className="space-y-6">
{recommendations.map(({ recommendation, user }) => (
<li key={recommendation.id} className="border rounded p-4">
<div className="flex justify-between items-start mb-2">
<h3 className="font-bold">
For: {user.firstName} {user.lastName}
</h3>
<span className="text-xs text-gray-500">
{new Date(recommendation.createdAt).toLocaleDateString()}
</span>
</div>
<div className="space-y-2 text-sm mb-4">
<div>
<span className="font-semibold">Advice:</span>{" "}
{recommendation.recommendationText}
</div>
<div>
<span className="font-semibold">Activity:</span>{" "}
{recommendation.activityPlan}
</div>
<div>
<span className="font-semibold">Diet:</span> {recommendation.dietPlan}
</div>
</div>
<div className="flex space-x-2">
<button
onClick={() => handleAction(recommendation.id, "approved")}
disabled={processingId === recommendation.id}
className="flex-1 bg-green-600 text-white py-2 rounded hover:bg-green-700 disabled:opacity-50 flex justify-center items-center"
>
{processingId === recommendation.id ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<>
<Check className="mr-2 h-4 w-4" /> Approve
</>
)}
</button>
<button
onClick={() => handleAction(recommendation.id, "rejected")}
disabled={processingId === recommendation.id}
className="flex-1 bg-red-600 text-white py-2 rounded hover:bg-red-700 disabled:opacity-50 flex justify-center items-center"
>
{processingId === recommendation.id ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<>
<X className="mr-2 h-4 w-4" /> Reject
</>
)}
</button>
</div>
</li>
))}
</ul>
);
}
+125
View File
@@ -0,0 +1,125 @@
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import {
LayoutDashboard,
Users,
CalendarCheck,
CreditCard,
Settings,
LogOut,
Brain,
} from "lucide-react";
import { UserButton, useUser } from "@clerk/nextjs";
interface Recommendation {
id: string;
status: string;
}
export function Sidebar() {
const pathname = usePathname();
const { user } = useUser();
const [pendingCount, setPendingCount] = useState(0);
useEffect(() => {
const fetchPending = async () => {
try {
const res = await fetch("/api/recommendations");
if (res.ok) {
const data = await res.json();
const pending = (data.recommendations || []).filter(
(r: Recommendation) => r.status === "pending"
);
setPendingCount(pending.length);
}
} catch (e) {
console.error("Failed to fetch pending recommendations", e);
}
};
fetchPending();
}, []);
const menuItems = [
{ icon: LayoutDashboard, label: "Dashboard", href: "/" },
{ icon: Users, label: "Users", href: "/users" },
{
icon: Brain,
label: (
<span className="flex items-center">
AI Recommendations
{pendingCount > 0 && (
<span className="ml-2 inline-block bg-red-600 text-xs rounded-full px-2 py-0.5">
{pendingCount}
</span>
)}
</span>
),
href: "/recommendations",
},
{ icon: CalendarCheck, label: "Attendance", href: "/attendance" },
{ icon: CreditCard, label: "Payments", href: "/payments" },
{ icon: Settings, label: "Settings", href: "/settings" },
];
return (
<aside className="w-64 bg-gradient-to-b from-slate-900 via-slate-900 to-slate-950 text-white h-screen fixed left-0 top-0 flex flex-col border-r border-slate-800/50 shadow-2xl">
{/* Logo Section */}
<div className="p-6 border-b border-slate-800/50">
<div className="flex items-center gap-3 justify-center">
<img
src="/nextform-logo.png"
alt="NextForm"
className="h-16 w-16 object-contain"
/>
<div>
<h1 className="text-lg font-black bg-gradient-to-r from-blue-400 via-cyan-400 to-blue-300 bg-clip-text text-transparent">
NextForm
</h1>
</div>
</div>
</div>
{/* Navigation */}
<nav className="flex-1 p-4 space-y-1 overflow-y-auto">
{menuItems.map((item) => {
const Icon = item.icon;
const isActive = pathname === item.href;
const label = typeof item.label === "string" ? item.label : item.label;
return (
<Link
key={item.href}
href={item.href}
className={`flex items-center gap-3 px-4 py-3 rounded-xl transition-all duration-200 group relative overflow-hidden ${isActive
? "bg-gradient-to-r from-blue-600 to-cyan-600 text-white shadow-lg shadow-blue-900/30"
: "text-slate-400 hover:bg-slate-800/40 hover:text-white"}`}
>
{isActive && <div className="absolute inset-0 bg-white/10 blur-xl"></div>}
<Icon size={20} className={`${isActive ? "text-white" : "text-slate-500 group-hover:text-white"} relative z-10`} />
<span className="font-semibold relative z-10">{label}</span>
</Link>
);
})}
</nav>
{/* User Section */}
<div className="p-4 border-t border-slate-800/50 bg-slate-800/20">
<div className="flex items-center gap-3 px-3 py-3 rounded-xl bg-slate-800/50 hover:bg-slate-800/70 transition-colors">
<div className="h-10 w-10 rounded-full bg-gradient-to-br from-blue-500 to-cyan-500 flex-shrink-0 overflow-hidden">
<UserButton afterSignOutUrl="/" />
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-semibold text-white truncate">
{user?.fullName || "Admin"}
</p>
<p className="text-xs text-slate-400 truncate">
{user?.emailAddresses[0]?.emailAddress || "admin@fitai.com"}
</p>
</div>
</div>
</div>
</aside>
);
}
@@ -0,0 +1,74 @@
import { LucideIcon } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
interface StatsCardProps {
title: string;
value: string | number;
change?: string;
trend?: "up" | "down" | "neutral";
icon: LucideIcon;
color?: "blue" | "green" | "purple" | "orange";
}
export function StatsCard({ title, value, change, trend, icon: Icon, color = "blue" }: StatsCardProps) {
const colorStyles = {
blue: {
bg: "from-blue-700 via-cyan-500 to-blue-600",
text: "text-white",
light: "from-blue-50 to-cyan-50",
badge: "bg-blue-200/60 text-blue-900 backdrop-blur-sm",
icon: "bg-white/20 text-white backdrop-blur-sm",
},
green: {
bg: "from-pink-700 via-fuchsia-500 to-pink-600",
text: "text-white",
light: "from-pink-50 to-rose-50",
badge: "bg-pink-200/60 text-pink-900 backdrop-blur-sm",
icon: "bg-white/20 text-white backdrop-blur-sm",
},
purple: {
bg: "from-amber-700 via-yellow-500 to-amber-600",
text: "text-white",
light: "from-amber-50 to-yellow-50",
badge: "bg-amber-200/60 text-amber-900 backdrop-blur-sm",
icon: "bg-white/20 text-white backdrop-blur-sm",
},
orange: {
bg: "from-emerald-700 via-teal-500 to-emerald-600",
text: "text-white",
light: "from-emerald-50 to-teal-50",
badge: "bg-emerald-200/60 text-emerald-900 backdrop-blur-sm",
icon: "bg-white/20 text-white backdrop-blur-sm",
},
};
const styles = colorStyles[color];
return (
<Card className={`bg-gradient-to-br ${styles.bg} border-0 shadow-2xl hover:shadow-2xl transition-all duration-500 overflow-hidden group h-full relative before:absolute before:inset-0 before:bg-gradient-to-br before:from-white/10 before:to-transparent before:pointer-events-none`}>
<CardHeader className="flex flex-row items-start justify-between space-y-0 pb-2.5 pt-5 px-5">
<CardTitle className={`text-xs font-bold uppercase tracking-wider ${styles.text} leading-tight max-w-[70%]`}>
{title}
</CardTitle>
<div className={`p-1.5 rounded-lg ${styles.icon} flex-shrink-0`}>
<Icon size={16} strokeWidth={2} />
</div>
</CardHeader>
<CardContent className="px-5 pb-5 space-y-2.5">
<div className={`text-2xl font-black ${styles.text}`}>
{value}
</div>
{change && (
<div className="flex items-center gap-1">
<span
className={`inline-flex items-center gap-0.5 font-bold px-2 py-0.5 rounded-md text-xs tracking-wide ${styles.badge}`}
>
{trend === "up" ? "↑" : trend === "down" ? "↓" : "→"} {change}
</span>
<span className="text-xs text-gray-600">vs month</span>
</div>
)}
</CardContent>
</Card>
);
}
+2
View File
@@ -0,0 +1,2 @@
// Re-export Button component with lowercase filename for compatibility
export { Button } from './Button';
+19 -52
View File
@@ -1,56 +1,23 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import React from 'react'
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary'
children: React.ReactNode
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";
export function Button({ variant = 'primary', children, className = '', ...props }: ButtonProps) {
const baseClasses = 'px-4 py-2 rounded-md font-medium transition-colors'
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
}
export { Button, buttonVariants };
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${className}`}
{...props}
>
{children}
</button>
)
}
+2
View File
@@ -0,0 +1,2 @@
// Re-export Card components with lowercase filename for compatibility
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from './Card';
+78
View File
@@ -0,0 +1,78 @@
import React from 'react'
interface CardProps {
children: React.ReactNode
className?: string
}
export function Card({ children, className = '' }: CardProps) {
return (
<div className={`bg-white rounded-lg shadow-md p-6 ${className}`}>
{children}
</div>
)
}
export function CardHeader({ children, className = '' }: CardProps) {
return (
<div className={`mb-4 ${className}`}>
{children}
</div>
)
}
export function CardContent({ children, className = '' }: CardProps) {
return (
<div className={className}>
{children}
</div>
)
}
export function CardTitle({ children, className = '' }: CardProps) {
return (
<h2 className={`text-lg font-semibold ${className}`}>
{children}
</h2>
)
}
export function CardDescription({ children, className = '' }: CardProps) {
return (
<p className={`text-sm text-gray-600 ${className}`}>
{children}
</p>
)
}
export function CardFooter({ children, className = '' }: CardProps) {
return (
<div className={`mt-4 ${className}`}>
{children}
</div>
)
}
export function CardTitle({ children, className = '' }: CardProps) {
return (
<h2 className={`text-lg font-semibold ${className}`}>
{children}
</h2>
)
}
export function CardDescription({ children, className = '' }: CardProps) {
return (
<p className={`text-sm text-gray-600 ${className}`}>
{children}
</p>
)
}
export function CardFooter({ children, className = '' }: CardProps) {
return (
<div className={`mt-4 ${className}`}>
{children}
</div>
)
}
@@ -0,0 +1,174 @@
"use client";
import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
interface Recommendation {
id: string;
userId: string;
type: "short_term" | "medium_term" | "long_term" | "ai_plan";
content: string;
activityPlan?: string;
dietPlan?: string;
status: "pending" | "completed" | "approved" | "rejected";
createdAt: string;
}
interface RecommendationsProps {
userId: string;
}
export function Recommendations({ userId }: RecommendationsProps) {
const [recommendations, setRecommendations] = useState<Recommendation[]>([]);
const [loading, setLoading] = useState(true);
const [newRec, setNewRec] = useState<{
type: "short_term" | "medium_term" | "long_term";
content: string;
}>({ type: "short_term", content: "" });
useEffect(() => {
fetchRecommendations();
}, [userId]);
const fetchRecommendations = async () => {
setLoading(true);
try {
const response = await fetch(`/api/recommendations?userId=${userId}`);
if (response.ok) {
const data = await response.json();
setRecommendations(data);
}
} catch (error) {
console.error("Failed to fetch recommendations:", error);
} finally {
setLoading(false);
}
};
const handleAddRecommendation = async (e: React.FormEvent) => {
e.preventDefault();
try {
const response = await fetch("/api/recommendations", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
userId,
type: newRec.type,
content: newRec.content,
}),
});
if (response.ok) {
setNewRec({ ...newRec, content: "" });
fetchRecommendations();
} else {
alert("Failed to add recommendation");
}
} catch (error) {
console.error(error);
}
};
const groupedRecs = {
ai_plan: recommendations.filter((r) => r.type === "ai_plan"),
short_term: recommendations.filter((r) => r.type === "short_term"),
medium_term: recommendations.filter((r) => r.type === "medium_term"),
long_term: recommendations.filter((r) => r.type === "long_term"),
};
const renderSection = (
title: string,
type: "short_term" | "medium_term" | "long_term" | "ai_plan",
items: Recommendation[]
) => (
<div className="mb-6">
<h4 className="font-semibold text-lg mb-3 capitalize">{title}</h4>
<div className="space-y-2">
{items.length === 0 && (
<p className="text-gray-500 text-sm italic">No recommendations yet.</p>
)}
{items.map((rec) => (
<div
key={rec.id}
className={`p-3 rounded border flex justify-between items-start ${rec.status === "completed" || rec.status === "approved"
? "bg-green-50 border-green-200"
: "bg-white border-gray-200"
}`}
>
<div className="w-full">
<p className="text-sm font-medium">{rec.content}</p>
{rec.type === 'ai_plan' && (
<div className="mt-2 text-xs text-gray-600 space-y-1">
{rec.activityPlan && <p><span className="font-semibold">Activity:</span> {rec.activityPlan}</p>}
{rec.dietPlan && <p><span className="font-semibold">Diet:</span> {rec.dietPlan}</p>}
</div>
)}
<p className="text-xs text-gray-400 mt-2">
{new Date(rec.createdAt).toLocaleDateString()} -{" "}
<span
className={
rec.status === "completed" || rec.status === "approved"
? "text-green-600 font-medium"
: "text-yellow-600"
}
>
{rec.status === "completed" ? "Completed" : rec.status === "approved" ? "Approved" : "Pending"}
</span>
</p>
</div>
</div>
))}
</div>
{type !== 'ai_plan' && (
<form onSubmit={handleAddRecommendation} className="mt-3 flex gap-2">
<input
type="hidden"
value={type}
onChange={() => setNewRec({ ...newRec, type: type as any })}
/>
{newRec.type === type && (
<>
<input
type="text"
placeholder={`Add ${title.toLowerCase()}...`}
className="flex-1 border rounded px-3 py-1 text-sm"
value={newRec.content}
onChange={(e) =>
setNewRec({ ...newRec, content: e.target.value })
}
required
/>
<Button type="submit" variant="secondary">
Add
</Button>
</>
)}
{newRec.type !== type && (
<Button type="button" variant="secondary" onClick={() => setNewRec({ type: type as any, content: "" })} className="text-xs text-gray-500">
+ Add New
</Button>
)}
</form>
)}
</div>
);
if (loading) return <div>Loading recommendations...</div>;
return (
<Card>
<CardHeader>
<h3 className="text-xl font-bold">Fitness Recommendations</h3>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{renderSection("Daily AI Plan", "ai_plan", groupedRecs.ai_plan)}
{renderSection("Short Term Goals", "short_term", groupedRecs.short_term)}
{renderSection("Medium Term Goals", "medium_term", groupedRecs.medium_term)}
{renderSection("Long Term Goals", "long_term", groupedRecs.long_term)}
</div>
</CardContent>
</Card>
);
}
+118 -30
View File
@@ -9,6 +9,20 @@ import { formatDate } from "@/lib/utils";
ModuleRegistry.registerModules([AllCommunityModule]);
function getTimeAgo(date: Date): string {
const now = new Date();
const diffMs = now.getTime() - date.getTime();
const diffMins = Math.floor(diffMs / 60000);
const diffHours = Math.floor(diffMins / 60);
const diffDays = Math.floor(diffHours / 24);
if (diffMins < 1) return 'just now';
if (diffMins < 60) return `${diffMins}m ago`;
if (diffHours < 24) return `${diffHours}h ago`;
return `${diffDays}d ago`;
}
interface User {
id: string;
email: string;
@@ -17,6 +31,8 @@ interface User {
role: string;
phone?: string;
createdAt: Date;
isCheckedIn?: boolean;
checkInTime?: Date;
client?: {
id: string;
membershipType: string;
@@ -70,6 +86,7 @@ export function UserGrid({
sortable: true,
cellRenderer: (params: any) => {
const roleColors = {
superAdmin: "bg-red-100 text-red-800",
admin: "bg-purple-100 text-purple-800",
trainer: "bg-blue-100 text-blue-800",
client: "bg-green-100 text-green-800",
@@ -77,7 +94,14 @@ export function UserGrid({
const colorClass =
roleColors[params.value as keyof typeof roleColors] ||
"bg-gray-100 text-gray-800";
return `<span class="px-2 py-1 rounded text-xs font-medium ${colorClass}">${params.value}</span>`;
const label = params.value === 'superAdmin' ? 'Super Admin' : params.value.charAt(0).toUpperCase() + params.value.slice(1);
return (
<span className={`px-2 py-1 rounded-full text-xs font-medium ${colorClass}`}>
{label}
</span>
);
},
minWidth: 120,
},
@@ -87,6 +111,7 @@ export function UserGrid({
filter: "agTextColumnFilter",
sortable: true,
minWidth: 130,
valueFormatter: (params: any) => params.value || "N/A",
},
{
headerName: "Membership",
@@ -94,17 +119,24 @@ export function UserGrid({
filter: "agTextColumnFilter",
sortable: true,
cellRenderer: (params: any) => {
if (!params.value || params.value === "N/A") return "N/A";
if (!params.value || params.value === "N/A") return <span className="text-gray-400">N/A</span>;
const membershipColors = {
vip: "bg-yellow-100 text-yellow-800",
premium: "bg-blue-100 text-blue-800",
basic: "bg-gray-100 text-gray-800",
vip: "bg-yellow-100 text-yellow-800 border-yellow-200",
premium: "bg-blue-100 text-blue-800 border-blue-200",
basic: "bg-slate-100 text-slate-800 border-slate-200",
};
const colorClass =
membershipColors[params.value as keyof typeof membershipColors] ||
"bg-gray-100 text-gray-800";
return `<span class="px-2 py-1 rounded text-xs font-medium ${colorClass}">${params.value}</span>`;
const label = params.value.charAt(0).toUpperCase() + params.value.slice(1);
return (
<span className={`px-2 py-1 rounded-full text-xs font-medium border ${colorClass}`}>
{label}
</span>
);
},
minWidth: 120,
},
@@ -114,20 +146,49 @@ export function UserGrid({
filter: "agTextColumnFilter",
sortable: true,
cellRenderer: (params: any) => {
if (!params.value || params.value === "N/A") return "N/A";
if (!params.value || params.value === "N/A") return <span className="text-gray-400">N/A</span>;
const statusColors = {
active: "bg-green-100 text-green-800",
inactive: "bg-red-100 text-red-800",
suspended: "bg-yellow-100 text-yellow-800",
suspended: "bg-orange-100 text-orange-800",
expired: "bg-gray-100 text-gray-800",
};
const colorClass =
statusColors[params.value as keyof typeof statusColors] ||
"bg-gray-100 text-gray-800";
return `<span class="px-2 py-1 rounded text-xs font-medium ${colorClass}">${params.value}</span>`;
const label = params.value.charAt(0).toUpperCase() + params.value.slice(1);
return (
<span className={`px-2 py-1 rounded-full text-xs font-medium ${colorClass}`}>
{label}
</span>
);
},
minWidth: 120,
},
{
headerName: "Currently Checked In",
valueGetter: (params) => params.data?.isCheckedIn,
filter: "agTextColumnFilter",
sortable: true,
cellRenderer: (params: any) => {
if (!params.data?.isCheckedIn) {
return <span className="text-gray-400">—</span>;
}
const checkInTime = params.data.checkInTime ? new Date(params.data.checkInTime) : null;
const timeAgo = checkInTime ? getTimeAgo(checkInTime) : '';
return (
<span className="px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 border border-green-200">
✓ Checked In {timeAgo && `(${timeAgo})`}
</span>
);
},
minWidth: 180,
},
{
headerName: "Join Date",
valueGetter: (params) =>
@@ -204,45 +265,72 @@ export function UserGrid({
};
return (
<div>
<div className="flex justify-between items-center mb-4">
<input
type="text"
placeholder="Search users..."
className="border border-gray-300 rounded px-4 py-2"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
<div className="flex gap-2">
<div className="space-y-4">
{/* Search and Actions Bar */}
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 bg-gradient-to-r from-slate-50 to-blue-50 p-4 rounded-xl border border-slate-200">
<div className="w-full sm:w-auto flex-1">
<div className="relative">
<svg className="absolute left-3 top-3 w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<input
type="text"
placeholder="Search athletes..."
className="w-full pl-10 pr-4 py-2.5 border border-slate-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white shadow-sm"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
</div>
<div className="flex gap-2 w-full sm:w-auto">
<button
className="bg-green-500 text-white px-4 py-2 rounded disabled:opacity-50"
className="flex-1 sm:flex-none bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white px-4 py-2.5 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed font-semibold transition-all shadow-md hover:shadow-lg"
onClick={handleEdit}
disabled={selectedUsers.length !== 1}
>
Edit User
✏️ Edit
</button>
<button
className="bg-red-500 text-white px-4 py-2 rounded disabled:opacity-50"
className="flex-1 sm:flex-none bg-gradient-to-r from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 text-white px-4 py-2.5 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed font-semibold transition-all shadow-md hover:shadow-lg"
onClick={handleDelete}
disabled={selectedUsers.length !== 1}
>
Delete User
🗑️ Delete
</button>
<button
className="bg-yellow-500 text-white px-4 py-2 rounded disabled:opacity-50"
className="flex-1 sm:flex-none bg-gradient-to-r from-orange-500 to-orange-600 hover:from-orange-600 hover:to-orange-700 text-white px-4 py-2.5 rounded-lg disabled:opacity-50 disabled:cursor-not-allowed font-semibold transition-all shadow-md hover:shadow-lg"
onClick={handleBulkDelete}
disabled={selectedUsers.length === 0}
>
Bulk Delete
⚡ Bulk
</button>
</div>
</div>
<div
className="ag-theme-alpine"
style={{ height: "600px", width: "100%" }}
>
<AgGridReact<User> {...gridOptions} ref={gridRef} />
{/* Table */}
<div className="bg-white rounded-2xl shadow-lg border border-slate-200 overflow-hidden">
<div
className="ag-theme-alpine"
style={{ height: "600px", width: "100%" }}
>
<AgGridReact<User> {...gridOptions} ref={gridRef} />
</div>
</div>
{/* Selected Count */}
{selectedUsers.length > 0 && (
<div className="flex items-center justify-between bg-gradient-to-r from-blue-500/10 to-cyan-500/10 border border-blue-200/50 px-4 py-3 rounded-lg">
<p className="text-sm font-semibold text-blue-700">
{selectedUsers.length} athlete{selectedUsers.length !== 1 ? 's' : ''} selected
</p>
<button
onClick={() => setSelectedUsers([])}
className="text-sm text-blue-600 hover:text-blue-700 font-medium"
>
Clear selection
</button>
</div>
)}
</div>
);
}
@@ -2,8 +2,8 @@
import { useState, useEffect } from "react";
import { UserGrid } from "@/components/users/UserGrid";
import { Button } from "@/components/ui/Button";
import { Card, CardHeader, CardContent } from "@/components/ui/Card";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardContent } from "@/components/ui/card";
interface User {
id: string;
@@ -13,6 +13,11 @@ interface User {
role: string;
phone?: string;
createdAt: Date;
isCheckedIn?: boolean;
checkInTime?: Date;
lastCheckInTime?: Date;
checkInsThisWeek?: number;
checkInsThisMonth?: number;
client?: {
id: string;
membershipType: string;
@@ -139,23 +144,44 @@ export function UserManagement() {
};
const handleSaveEdit = async () => {
if (!editForm || !selectedUser) return;
if (!editForm) return;
try {
const response = await fetch("/api/users", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: selectedUser.id, ...editForm }),
});
if (response.ok) {
setIsEditing(false);
setEditForm(null);
fetchUsers();
if (selectedUser) {
// Update existing user
const response = await fetch("/api/users", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: selectedUser.id, ...editForm }),
});
if (response.ok) {
setIsEditing(false);
setEditForm(null);
fetchUsers();
} else {
alert("Error updating user");
}
} else {
alert("Error updating user");
// Create (Invite) new user
const response = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(editForm),
});
if (response.ok) {
setIsEditing(false);
setEditForm(null);
fetchUsers();
alert("Invitation sent successfully!");
} else {
const errorData = await response.json();
alert(`Error sending invitation: ${errorData.error}`);
}
}
} catch (error) {
console.error(error);
alert("An unexpected error occurred");
}
};
@@ -179,70 +205,106 @@ export function UserManagement() {
};
return (
<div className="space-y-6">
<div className="flex justify-between items-center">
<h2 className="text-2xl font-bold">User Management</h2>
<div className="flex gap-2">
<Button
variant={filter === "all" ? "primary" : "secondary"}
onClick={() => setFilter("all")}
>
All Users
</Button>
<Button
variant="secondary"
onClick={handleEditUser}
disabled={!selectedUser}
>
Edit User
</Button>
<Button
variant="secondary"
onClick={handleDeleteUser}
disabled={!selectedUser}
>
Delete User
</Button>
<Button
variant={filter === "client" ? "primary" : "secondary"}
onClick={() => setFilter("client")}
>
Clients
</Button>
<Button
variant={filter === "trainer" ? "primary" : "secondary"}
onClick={() => setFilter("trainer")}
>
Trainers
</Button>
<Button
variant={filter === "admin" ? "primary" : "secondary"}
onClick={() => setFilter("admin")}
>
Admins
</Button>
</div>
<div className="space-y-4">
{/* Header Section */}
<div>
<h3 className="text-lg font-bold text-gray-900">User Management</h3>
<p className="text-sm text-gray-600 mt-1">Manage and monitor your fitness clients</p>
</div>
<div className="flex justify-between items-center">
<div className="text-sm text-gray-600">
Showing {users.length} users
{selectedUser && (
<span className="ml-4 text-blue-600">
Selected: {selectedUser.firstName} {selectedUser.lastName}
</span>
)}
</div>
<div className="flex gap-2">
<Button variant="secondary" onClick={handleRefresh}>
Refresh
</Button>
<Button variant="secondary" onClick={handleExport}>
Export CSV
</Button>
</div>
{/* Filter Buttons */}
<div className="flex flex-wrap gap-2">
<Button
variant={filter === "all" ? "primary" : "secondary"}
onClick={() => setFilter("all")}
className="text-xs"
>
All Users
</Button>
<Button
variant={filter === "client" ? "primary" : "secondary"}
onClick={() => setFilter("client")}
className="text-xs"
>
Clients
</Button>
<Button
variant={filter === "trainer" ? "primary" : "secondary"}
onClick={() => setFilter("trainer")}
className="text-xs"
>
Trainers
</Button>
<Button
variant={filter === "admin" ? "primary" : "secondary"}
onClick={() => setFilter("admin")}
className="text-xs"
>
Admins
</Button>
<Button
variant={filter === "superAdmin" ? "primary" : "secondary"}
onClick={() => setFilter("superAdmin")}
className="text-xs"
>
Super Admins
</Button>
</div>
{/* Action Buttons */}
<div className="flex flex-wrap gap-2">
<Button
variant="secondary"
onClick={() => selectedUser && handleEditUser(selectedUser)}
disabled={!selectedUser}
className="text-xs"
>
Edit User
</Button>
<Button
variant="secondary"
onClick={() => {
setEditForm({
firstName: "",
lastName: "",
email: "",
role: "client",
phone: "",
});
setSelectedUser(null);
setIsEditing(true);
}}
className="text-xs"
>
Invite User
</Button>
<Button
variant="secondary"
onClick={() => selectedUser && handleDeleteUser(selectedUser)}
disabled={!selectedUser}
className="text-xs"
>
Delete User
</Button>
<Button variant="secondary" onClick={handleRefresh} className="text-xs">
Refresh
</Button>
<Button variant="secondary" onClick={handleExport} className="text-xs">
Export CSV
</Button>
</div>
{/* Stats */}
<div className="text-sm text-gray-600 px-4 py-2 bg-gray-50 rounded-lg">
Showing {users.length} users
{selectedUser && (
<span className="ml-4 text-blue-600 font-medium">
Selected: {selectedUser.firstName} {selectedUser.lastName}
</span>
)}
</div>
{/* User Grid */}
<Card>
<CardContent className="p-0">
<UserGrid
@@ -259,7 +321,7 @@ export function UserManagement() {
{isEditing && editForm && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white p-6 rounded-lg shadow-lg max-w-md w-full">
<h3 className="text-lg font-semibold mb-4">Edit User</h3>
<h3 className="text-lg font-semibold mb-4">{selectedUser ? 'Edit User' : 'Invite New User'}</h3>
<form
onSubmit={(e) => {
e.preventDefault();
@@ -304,6 +366,7 @@ export function UserManagement() {
}
className="w-full border border-gray-300 rounded px-3 py-2"
required
disabled={!!selectedUser} // Disable email edit for existing users if desired, or keep enabled
/>
</div>
<div className="mb-4">
@@ -316,10 +379,17 @@ export function UserManagement() {
className="w-full border border-gray-300 rounded px-3 py-2"
required
>
{/* Ideally we fetch current user role to filter these.
For now, we show all but the API will enforce it.
We can add a visual indicator or fetch "me" to filter. */}
<option value="client">Client</option>
<option value="trainer">Trainer</option>
<option value="admin">Admin</option>
<option value="superAdmin">Super Admin</option>
</select>
<p className="text-xs text-gray-500 mt-1">
Note: You can only assign roles lower than your own.
</p>
</div>
<div className="mb-4">
<label className="block text-sm font-medium mb-1">Phone</label>
@@ -347,7 +417,7 @@ export function UserManagement() {
type="submit"
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
Save
{selectedUser ? 'Save Changes' : 'Send Invitation'}
</button>
</div>
</form>
@@ -383,11 +453,17 @@ export function UserManagement() {
{selectedUser && (
<Card>
<CardHeader>
<CardHeader className="flex flex-row items-center justify-between">
<h3 className="text-lg font-semibold">User Details</h3>
<a
href={`/users/${selectedUser.id}`}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm font-medium"
>
View Full Profile & Recommendations
</a>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-3 gap-4">
<div>
<h4 className="font-medium mb-2">Basic Information</h4>
<div className="space-y-1 text-sm">
@@ -436,13 +512,35 @@ export function UserManagement() {
<span className="font-medium">Last Visit:</span>{" "}
{selectedUser.client.lastVisit
? new Date(
selectedUser.client.lastVisit,
).toLocaleDateString()
selectedUser.client.lastVisit,
).toLocaleDateString()
: "Never"}
</p>
</div>
</div>
)}
<div>
<h4 className="font-medium mb-2">Check-In Statistics</h4>
<div className="space-y-1 text-sm">
<p>
<span className="font-medium">Last Check-In:</span>{" "}
{selectedUser.lastCheckInTime
? new Date(
selectedUser.lastCheckInTime,
).toLocaleString()
: "Never"}
</p>
<p>
<span className="font-medium">This Week:</span>{" "}
{selectedUser.checkInsThisWeek || 0} check-ins
</p>
<p>
<span className="font-medium">This Month:</span>{" "}
{selectedUser.checkInsThisMonth || 0} check-ins
</p>
</div>
</div>
</div>
</CardContent>
</Card>
+88
View File
@@ -0,0 +1,88 @@
import { getDatabase } from '@/lib/database';
import type { FitnessGoal } from '@/lib/database/types';
// Import types from database package
import type {
FitnessProfile as DBFitnessProfile,
Recommendation as DBRecommendation,
} from '@fitai/database';
export interface AIContext {
profile: DBFitnessProfile;
activeGoals: FitnessGoal[];
completedGoals: FitnessGoal[];
recentRecommendations: DBRecommendation[];
progressSummary: {
goalsCompleted: number;
goalsActive: number;
averageProgress: number;
};
}
/**
* Build comprehensive AI context for a user
* Aggregates fitness profile, goals, and recommendation history
*/
export async function buildAIContext(userId: string): Promise<AIContext> {
const db = await getDatabase();
// Fetch fitness profile
const profile = await db.getFitnessProfileByUserId(userId);
if (!profile) {
throw new Error(`Fitness profile not found for user ${userId}`);
}
// Fetch all fitness goals
const allGoals = await db.getFitnessGoalsByUserId(userId);
// Separate active and completed goals
const activeGoals = allGoals.filter((g) => g.status === 'active');
const completedGoals = allGoals.filter((g) => g.status === 'completed');
// Get all recommendations
const allRecommendations = await db.getRecommendationsByUserId(userId);
// Filter recent recommendations (last 7 days)
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
const recentRecommendations = allRecommendations
.filter((r) => new Date(r.createdAt) > sevenDaysAgo)
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
.slice(0, 5);
// Calculate progress summary
const progressSummary = {
goalsCompleted: completedGoals.length,
goalsActive: activeGoals.length,
averageProgress:
activeGoals.length > 0
? activeGoals.reduce((sum, g) => sum + (g.progress || 0), 0) / activeGoals.length
: 0,
};
return {
profile,
activeGoals,
completedGoals,
recentRecommendations,
progressSummary,
};
}
/**
* Format goal for display in AI prompt
*/
export function formatGoalForPrompt(goal: FitnessGoal): string {
const progress = goal.progress || 0;
const current = goal.currentValue || 0;
const target = goal.targetValue;
const unit = goal.unit || '';
if (target) {
return `${goal.title}: ${current}/${target} ${unit} (${progress.toFixed(1)}% complete)`;
}
return `${goal.title}: ${progress.toFixed(1)}% complete`;
}
+91
View File
@@ -0,0 +1,91 @@
import type { AIContext } from './ai-context';
import { formatGoalForPrompt } from './ai-context';
/**
* Build enhanced AI prompt with comprehensive user context
* Includes profile, goals, progress, and recommendation history
*/
export function buildEnhancedPrompt(context: AIContext): string {
const { profile, activeGoals, completedGoals, recentRecommendations, progressSummary } = context;
// Build goals section
const activeGoalsText =
activeGoals.length > 0
? activeGoals.map((g) => `- ${formatGoalForPrompt(g)}`).join('\n')
: '- No active goals set';
const completedGoalsText =
completedGoals.length > 0
? completedGoals.slice(0, 3).map((g) => g.title).join(', ')
: 'None yet';
// Build context about recent recommendations
const recommendationContextText =
recentRecommendations.length > 0
? `The user has received ${recentRecommendations.length} recommendations in the past week. Consider their progress and avoid repetitive advice.`
: 'This is a new user or they haven\'t received recent recommendations. Provide comprehensive guidance.';
return `You are a professional fitness trainer and nutritionist with access to the user's complete fitness journey.
## User Profile
- Height: ${profile.height || 'Not specified'} cm
- Weight: ${profile.weight || 'Not specified'} kg
- Age: ${profile.age || 'Not specified'}
- Gender: ${profile.gender || 'Not specified'}
- Primary Goal: ${profile.fitnessGoal || 'General fitness'}
- Activity Level: ${profile.activityLevel || 'Not specified'}
- Medical Conditions: ${profile.medicalConditions || 'None'}
- Allergies: ${profile.allergies || 'None'}
- Injuries: ${profile.injuries || 'None'}
## Active Goals (${activeGoals.length})
${activeGoalsText}
## Recent Progress
- Goals Completed: ${progressSummary.goalsCompleted}
- Active Goals: ${progressSummary.goalsActive}
- Average Progress on Active Goals: ${progressSummary.averageProgress.toFixed(1)}%
${completedGoals.length > 0 ? `- Recently Completed: ${completedGoalsText}` : ''}
## Recommendation History
${recommendationContextText}
## Task
Generate a personalized daily recommendation that:
1. Acknowledges their progress on active goals
2. Provides specific, actionable steps toward goal completion
3. Builds on previous recommendations without being repetitive
4. Adapts to their current progress level
5. Takes into account their medical conditions, allergies, and injuries
Respond in the following JSON format ONLY, no other text. Do not use markdown formatting or code blocks:
{
"recommendationText": "Personalized motivation and progress acknowledgment (2-3 sentences)",
"activityPlan": "Specific workout plan aligned with active goals (detailed, 3-5 exercises or activities)",
"dietPlan": "Nutrition plan supporting their goals and restrictions (detailed, include meals and portions)"
}`;
}
/**
* Build basic prompt for users without complete context
* Fallback when goals or other data is missing
*/
export function buildBasicPrompt(profile: any): string {
return `You are a professional fitness trainer and nutritionist.
Generate a detailed daily recommendation for a user with the following profile:
- Height: ${profile.height} cm
- Weight: ${profile.weight} kg
- Age: ${profile.age}
- Gender: ${profile.gender}
- Goal: ${profile.fitnessGoal}
- Activity Level: ${profile.activityLevel}
- Medical Conditions: ${profile.medicalConditions || "None"}
- Injuries: ${profile.injuries || "None"}
Please provide the response in the following JSON format ONLY, no other text. Do not use markdown formatting or code blocks:
{
"recommendationText": "General advice and motivation for today.",
"activityPlan": "Detailed workout or activity plan for today.",
"dietPlan": "Detailed meal plan for today."
}`;
}
-37
View File
@@ -1,37 +0,0 @@
export interface User {
id: string
email: string
firstName: string
lastName: string
password: string
phone?: string
role: 'admin' | 'client'
createdAt: Date
updatedAt: Date
}
export interface Client {
id: string
userId: string
membershipType: 'basic' | 'premium' | 'vip'
membershipStatus: 'active' | 'inactive' | 'expired'
joinDate: Date
}
export interface FitnessProfile {
userId: string
height: string
weight: string
age: string
gender: 'male' | 'female' | 'other'
activityLevel: 'sedentary' | 'light' | 'moderate' | 'active' | 'very_active'
fitnessGoals: string[]
exerciseHabits: string
dietHabits: string
medicalConditions: string
}
// In-memory database
export const users: User[] = []
export const clients: Client[] = []
export const fitnessProfiles: FitnessProfile[] = []
+529 -30
View File
@@ -1,7 +1,7 @@
import Database from 'better-sqlite3'
import path from 'path'
import fs from 'fs'
import { IDatabase, User, Client, FitnessProfile, DatabaseConfig } from './types'
import { IDatabase, User, Client, FitnessProfile, Attendance, Recommendation, DatabaseConfig } from './types'
export class SQLiteDatabase implements IDatabase {
private db: Database.Database | null = null
@@ -14,21 +14,21 @@ export class SQLiteDatabase implements IDatabase {
async connect(): Promise<void> {
try {
const dbPath = this.config.connection.filename || path.join(process.cwd(), 'data', 'fitai.db')
// Ensure data directory exists
const dataDir = path.dirname(dbPath)
if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir, { recursive: true })
}
this.db = new Database(dbPath)
// Enable foreign keys
this.db.exec('PRAGMA foreign_keys = ON')
// Create tables
await this.createTables()
if (this.config.options?.logging) {
console.log('SQLite database connected successfully at:', dbPath)
}
@@ -60,7 +60,7 @@ export class SQLiteDatabase implements IDatabase {
lastName TEXT NOT NULL,
password TEXT NOT NULL,
phone TEXT,
role TEXT NOT NULL CHECK (role IN ('admin', 'client')),
role TEXT NOT NULL CHECK (role IN ('superAdmin', 'admin', 'trainer', 'client')),
createdAt DATETIME NOT NULL,
updatedAt DATETIME NOT NULL
)
@@ -91,6 +91,8 @@ export class SQLiteDatabase implements IDatabase {
exerciseHabits TEXT,
dietHabits TEXT,
medicalConditions TEXT,
allergies TEXT,
injuries TEXT,
createdAt DATETIME NOT NULL,
updatedAt DATETIME NOT NULL,
FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE
@@ -103,29 +105,118 @@ export class SQLiteDatabase implements IDatabase {
CREATE INDEX IF NOT EXISTS idx_clients_userId ON clients(userId);
CREATE INDEX IF NOT EXISTS idx_fitness_profiles_userId ON fitness_profiles(userId);
`)
// Attendance table migration: change from clientId to userId
// Check if old table exists and migrate
const tableInfo = this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='attendance'").get() as any;
if (tableInfo) {
// Check if table has clientId column (old schema)
const columns = this.db.prepare("PRAGMA table_info(attendance)").all() as any[];
const hasClientId = columns.some((col: any) => col.name === 'clientId');
if (hasClientId) {
console.log('Migrating attendance table from clientId to userId...');
// Create new table with userId
this.db.exec(`
CREATE TABLE IF NOT EXISTS attendance_new (
id TEXT PRIMARY KEY,
userId TEXT NOT NULL,
checkInTime DATETIME NOT NULL,
checkOutTime DATETIME,
type TEXT NOT NULL CHECK (type IN ('gym', 'class', 'personal_training')),
notes TEXT,
createdAt DATETIME NOT NULL,
FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE
)
`);
// Migrate data: map clientId to userId via clients table
this.db.exec(`
INSERT INTO attendance_new (id, userId, checkInTime, checkOutTime, type, notes, createdAt)
SELECT a.id, c.userId, a.checkInTime, a.checkOutTime, a.type, a.notes, a.createdAt
FROM attendance a
JOIN clients c ON a.clientId = c.id
`);
// Drop old table and rename new one
this.db.exec(`DROP TABLE attendance`);
this.db.exec(`ALTER TABLE attendance_new RENAME TO attendance`);
console.log('Attendance table migration completed');
}
} else {
// Create new attendance table with userId
this.db.exec(`
CREATE TABLE IF NOT EXISTS attendance (
id TEXT PRIMARY KEY,
userId TEXT NOT NULL,
checkInTime DATETIME NOT NULL,
checkOutTime DATETIME,
type TEXT NOT NULL CHECK (type IN ('gym', 'class', 'personal_training')),
notes TEXT,
createdAt DATETIME NOT NULL,
FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE
)
`);
}
// Recommendations table
// Removed DROP TABLE to persist data. Schema is now stable.
// this.db.exec(`DROP TABLE IF EXISTS recommendations`)
this.db.exec(`
CREATE TABLE IF NOT EXISTS recommendations (
id TEXT PRIMARY KEY,
userId TEXT NOT NULL,
fitnessProfileId TEXT,
type TEXT NOT NULL,
content TEXT NOT NULL,
activityPlan TEXT,
dietPlan TEXT,
status TEXT NOT NULL CHECK (status IN ('pending', 'approved', 'rejected', 'completed')),
createdAt DATETIME NOT NULL,
approvedAt DATETIME,
approvedBy TEXT,
FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE,
FOREIGN KEY (fitnessProfileId) REFERENCES fitness_profiles (userId)
)
`);
this.db.exec(`
CREATE INDEX IF NOT EXISTS idx_recommendations_userId ON recommendations(userId);
`);
this.db.exec(`
CREATE INDEX IF NOT EXISTS idx_attendance_userId ON attendance(userId);
CREATE INDEX IF NOT EXISTS idx_attendance_checkInTime ON attendance(checkInTime);
`);
}
// User operations
async createUser(userData: Omit<User, 'id' | 'createdAt' | 'updatedAt'>): Promise<User> {
async createUser(
userData: Omit<User, "createdAt" | "updatedAt" | "id"> & { id?: string },
): Promise<User> {
if (!this.db) throw new Error('Database not connected')
const id = Math.random().toString(36).substr(2, 9)
const id = userData.id || Math.random().toString(36).substr(2, 9)
const now = new Date()
const user: User = {
id,
...userData,
id,
createdAt: now,
updatedAt: now
}
const stmt = this.db.prepare(
`INSERT INTO users (id, email, firstName, lastName, password, phone, role, createdAt, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
`INSERT INTO users(id, email, firstName, lastName, password, phone, role, createdAt, updatedAt)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
stmt.run(
user.id, user.email, user.firstName, user.lastName, user.password,
user.id, user.email, user.firstName, user.lastName, user.password,
user.phone, user.role, user.createdAt.toISOString(), user.updatedAt.toISOString()
)
@@ -170,7 +261,7 @@ export class SQLiteDatabase implements IDatabase {
values.push(new Date().toISOString()) // updatedAt
values.push(id)
const stmt = this.db.prepare(`UPDATE users SET ${setClause}, updatedAt = ? WHERE id = ?`)
const stmt = this.db.prepare(`UPDATE users SET ${setClause}, updatedAt = ? WHERE id = ? `)
stmt.run(values)
return this.getUserById(id)
@@ -184,6 +275,20 @@ export class SQLiteDatabase implements IDatabase {
return (result.changes || 0) > 0
}
async migrateUserId(oldId: string, newId: string): Promise<void> {
if (!this.db) throw new Error('Database not connected')
// We need to disable foreign keys temporarily if we want to update ID without cascade (if cascade isn't set)
// But we should try to update and let cascade handle it if possible.
// Since we didn't set ON UPDATE CASCADE, we might need to manually update references or use PRAGMA.
// Simplest way: Update the ID. If it fails due to FK, we have to handle it.
// For the Super Admin seed case, there are no dependencies.
const stmt = this.db.prepare('UPDATE users SET id = ? WHERE id = ?')
stmt.run(newId, oldId)
}
// Client operations
async createClient(clientData: Omit<Client, 'id'>): Promise<Client> {
if (!this.db) throw new Error('Database not connected')
@@ -192,12 +297,12 @@ export class SQLiteDatabase implements IDatabase {
const client: Client = { id, ...clientData }
const stmt = this.db.prepare(
`INSERT INTO clients (id, userId, membershipType, membershipStatus, joinDate)
VALUES (?, ?, ?, ?, ?)`
`INSERT INTO clients(id, userId, membershipType, membershipStatus, joinDate)
VALUES(?, ?, ?, ?, ?)`
)
stmt.run(
client.id, client.userId, client.membershipType,
client.id, client.userId, client.membershipType,
client.membershipStatus, client.joinDate.toISOString()
)
@@ -238,7 +343,7 @@ export class SQLiteDatabase implements IDatabase {
const values = fields.map(field => (updates as any)[field])
values.push(id)
const stmt = this.db.prepare(`UPDATE clients SET ${setClause} WHERE id = ?`)
const stmt = this.db.prepare(`UPDATE clients SET ${setClause} WHERE id = ? `)
stmt.run(values)
return this.getClientById(id)
@@ -264,17 +369,17 @@ export class SQLiteDatabase implements IDatabase {
}
const stmt = this.db.prepare(
`INSERT INTO fitness_profiles
(userId, height, weight, age, gender, activityLevel, fitnessGoals,
exerciseHabits, dietHabits, medicalConditions, createdAt, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
`INSERT INTO fitness_profiles
(userId, height, weight, age, gender, activityLevel, fitnessGoals,
exerciseHabits, dietHabits, medicalConditions, allergies, injuries, createdAt, updatedAt)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
stmt.run(
profile.userId, profile.height, profile.weight, profile.age, profile.gender,
profile.activityLevel, JSON.stringify(profile.fitnessGoals), profile.exerciseHabits,
profile.dietHabits, profile.medicalConditions, profile.createdAt.toISOString(),
profile.updatedAt.toISOString()
profile.dietHabits, profile.medicalConditions, profile.allergies, profile.injuries,
profile.createdAt.toISOString(), profile.updatedAt.toISOString()
)
return profile
@@ -311,7 +416,7 @@ export class SQLiteDatabase implements IDatabase {
values.push(new Date().toISOString()) // updatedAt
values.push(userId)
const stmt = this.db.prepare(`UPDATE fitness_profiles SET ${setClause}, updatedAt = ? WHERE userId = ?`)
const stmt = this.db.prepare(`UPDATE fitness_profiles SET ${setClause}, updatedAt = ? WHERE userId = ? `)
stmt.run(values)
return this.getFitnessProfileByUserId(userId)
@@ -325,6 +430,82 @@ export class SQLiteDatabase implements IDatabase {
return (result.changes || 0) > 0
}
// Attendance operations
async checkIn(userId: string, type: 'gym' | 'class' | 'personal_training', notes?: string): Promise<Attendance> {
if (!this.db) throw new Error('Database not connected')
const id = Math.random().toString(36).substr(2, 9)
const now = new Date()
const attendance: Attendance = {
id,
userId,
checkInTime: now,
type,
notes,
createdAt: now
}
const stmt = this.db.prepare(
`INSERT INTO attendance(id, userId, checkInTime, type, notes, createdAt)
VALUES(?, ?, ?, ?, ?, ?)`
)
stmt.run(
attendance.id, attendance.userId, attendance.checkInTime.toISOString(),
attendance.type, attendance.notes, attendance.createdAt.toISOString()
)
// Update client last visit if user is a client
const client = await this.getClientByUserId(userId);
if (client) {
this.db.prepare('UPDATE clients SET lastVisit = ? WHERE id = ?').run(
now.toISOString(),
client.id
);
}
return attendance
}
async checkOut(attendanceId: string): Promise<Attendance | null> {
if (!this.db) throw new Error('Database not connected')
const now = new Date()
const stmt = this.db.prepare('UPDATE attendance SET checkOutTime = ? WHERE id = ?')
stmt.run(now.toISOString(), attendanceId)
return this.getAttendanceById(attendanceId)
}
async getAttendanceById(id: string): Promise<Attendance | null> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM attendance WHERE id = ?')
const row = stmt.get(id)
return row ? this.mapRowToAttendance(row) : null
}
async getAttendanceHistory(userId: string): Promise<Attendance[]> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM attendance WHERE userId = ? ORDER BY checkInTime DESC')
const rows = stmt.all(userId)
return rows.map(row => this.mapRowToAttendance(row))
}
async getAllAttendance(): Promise<Attendance[]> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM attendance ORDER BY checkInTime DESC')
const rows = stmt.all()
return rows.map(row => this.mapRowToAttendance(row))
}
async getActiveCheckIn(userId: string): Promise<Attendance | null> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM attendance WHERE userId = ? AND checkOutTime IS NULL ORDER BY checkInTime DESC LIMIT 1')
const row = stmt.get(userId)
return row ? this.mapRowToAttendance(row) : null
}
// Helper methods to map database rows to entities
private mapRowToUser(row: any): User {
return {
@@ -346,7 +527,8 @@ export class SQLiteDatabase implements IDatabase {
userId: row.userId,
membershipType: row.membershipType,
membershipStatus: row.membershipStatus,
joinDate: new Date(row.joinDate)
joinDate: new Date(row.joinDate),
lastVisit: row.lastVisit ? new Date(row.lastVisit) : undefined
}
}
@@ -362,8 +544,325 @@ export class SQLiteDatabase implements IDatabase {
exerciseHabits: row.exerciseHabits,
dietHabits: row.dietHabits,
medicalConditions: row.medicalConditions,
allergies: row.allergies,
injuries: row.injuries,
createdAt: new Date(row.createdAt),
updatedAt: new Date(row.updatedAt)
}
}
private mapRowToAttendance(row: any): Attendance {
return {
id: row.id,
userId: row.userId,
checkInTime: new Date(row.checkInTime),
checkOutTime: row.checkOutTime ? new Date(row.checkOutTime) : undefined,
type: row.type,
notes: row.notes,
createdAt: new Date(row.createdAt)
}
}
// Recommendation operations
async createRecommendation(data: Omit<Recommendation, 'createdAt' | 'approvedAt' | 'approvedBy'>): Promise<Recommendation> {
if (!this.db) throw new Error('Database not connected')
const now = new Date()
const recommendation: Recommendation = {
...data,
createdAt: now,
status: data.status || 'pending'
}
const stmt = this.db.prepare(
`INSERT INTO recommendations (
id, userId, fitnessProfileId, type, content,
activityPlan, dietPlan, status, createdAt
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
stmt.run(
recommendation.id, recommendation.userId, recommendation.fitnessProfileId,
recommendation.type, recommendation.content, recommendation.activityPlan,
recommendation.dietPlan, recommendation.status,
recommendation.createdAt.toISOString()
)
return recommendation
}
async getRecommendationsByUserId(userId: string): Promise<Recommendation[]> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM recommendations WHERE userId = ? ORDER BY createdAt DESC')
const rows = stmt.all(userId)
return rows.map(row => this.mapRowToRecommendation(row))
}
async getAllRecommendations(): Promise<Recommendation[]> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM recommendations ORDER BY createdAt DESC')
const rows = stmt.all()
return rows.map(row => this.mapRowToRecommendation(row))
}
async updateRecommendation(id: string, updates: Partial<Recommendation>): Promise<Recommendation | null> {
if (!this.db) throw new Error('Database not connected')
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'userId')
if (fields.length === 0) {
const stmt = this.db.prepare('SELECT * FROM recommendations WHERE id = ?')
const row = stmt.get(id)
return row ? this.mapRowToRecommendation(row) : null
}
const setClause = fields.map(field => `${field} = ?`).join(', ')
const values = fields.map(field => {
const val = (updates as any)[field]
return val instanceof Date ? val.toISOString() : val
})
values.push(id)
const stmt = this.db.prepare(`UPDATE recommendations SET ${setClause} WHERE id = ?`)
stmt.run(values)
const getStmt = this.db.prepare('SELECT * FROM recommendations WHERE id = ?')
const row = getStmt.get(id)
return row ? this.mapRowToRecommendation(row) : null
}
async deleteRecommendation(id: string): Promise<boolean> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('DELETE FROM recommendations WHERE id = ?')
const result = stmt.run(id)
return (result.changes || 0) > 0
}
private mapRowToRecommendation(row: any): Recommendation {
return {
id: row.id,
userId: row.userId,
fitnessProfileId: row.fitnessProfileId,
type: row.type,
content: row.content,
activityPlan: row.activityPlan,
dietPlan: row.dietPlan,
status: row.status,
createdAt: new Date(row.createdAt),
approvedAt: row.approvedAt ? new Date(row.approvedAt) : undefined,
approvedBy: row.approvedBy
}
}
// Fitness Goals operations
async createFitnessGoal(goalData: Omit<import('./types').FitnessGoal, 'createdAt' | 'updatedAt'>): Promise<import('./types').FitnessGoal> {
if (!this.db) throw new Error('Database not connected')
const now = new Date()
const goal: import('./types').FitnessGoal = {
...goalData,
createdAt: now,
updatedAt: now
}
const stmt = this.db.prepare(
`INSERT INTO fitness_goals (
id, user_id, fitness_profile_id, goal_type, title, description,
target_value, current_value, unit, start_date, target_date,
completed_date, status, progress, priority, notes, created_at, updated_at
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
)
stmt.run(
goal.id,
goal.userId,
goal.fitnessProfileId || null,
goal.goalType,
goal.title,
goal.description || null,
goal.targetValue || null,
goal.currentValue || null,
goal.unit || null,
goal.startDate.toISOString(),
goal.targetDate ? goal.targetDate.toISOString() : null,
goal.completedDate ? goal.completedDate.toISOString() : null,
goal.status,
goal.progress,
goal.priority,
goal.notes || null,
goal.createdAt.toISOString(),
goal.updatedAt.toISOString()
)
return goal
}
async getFitnessGoalById(id: string): Promise<import('./types').FitnessGoal | null> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('SELECT * FROM fitness_goals WHERE id = ?')
const row = stmt.get(id)
return row ? this.mapRowToFitnessGoal(row) : null
}
async getFitnessGoalsByUserId(userId: string, status?: string): Promise<import('./types').FitnessGoal[]> {
if (!this.db) throw new Error('Database not connected')
let query = 'SELECT * FROM fitness_goals WHERE user_id = ?'
const params: any[] = [userId]
if (status) {
query += ' AND status = ?'
params.push(status)
}
query += ' ORDER BY created_at DESC'
const stmt = this.db.prepare(query)
const rows = stmt.all(...params)
return rows.map(row => this.mapRowToFitnessGoal(row))
}
async updateFitnessGoal(id: string, updates: Partial<import('./types').FitnessGoal>): Promise<import('./types').FitnessGoal | null> {
if (!this.db) throw new Error('Database not connected')
const fields = Object.keys(updates).filter(key => key !== 'id' && key !== 'createdAt')
if (fields.length === 0) return this.getFitnessGoalById(id)
// Map camelCase to snake_case for database columns
const columnMap: Record<string, string> = {
userId: 'user_id',
fitnessProfileId: 'fitness_profile_id',
goalType: 'goal_type',
targetValue: 'target_value',
currentValue: 'current_value',
startDate: 'start_date',
targetDate: 'target_date',
completedDate: 'completed_date',
updatedAt: 'updated_at'
}
const setClause = fields.map(field => `${columnMap[field] || field} = ?`).join(', ')
const values = fields.map(field => {
const val = (updates as any)[field]
return val instanceof Date ? val.toISOString() : val
})
values.push(new Date().toISOString()) // updatedAt
values.push(id)
const stmt = this.db.prepare(`UPDATE fitness_goals SET ${setClause}, updated_at = ? WHERE id = ?`)
stmt.run(values)
return this.getFitnessGoalById(id)
}
async deleteFitnessGoal(id: string): Promise<boolean> {
if (!this.db) throw new Error('Database not connected')
const stmt = this.db.prepare('DELETE FROM fitness_goals WHERE id = ?')
const result = stmt.run(id)
return (result.changes || 0) > 0
}
async updateGoalProgress(id: string, currentValue: number): Promise<import('./types').FitnessGoal | null> {
if (!this.db) throw new Error('Database not connected')
// Get the goal to calculate progress
const goal = await this.getFitnessGoalById(id)
if (!goal) return null
let progress = goal.progress
if (goal.targetValue && goal.targetValue > 0) {
progress = Math.min(100, (currentValue / goal.targetValue) * 100)
}
const stmt = this.db.prepare(
'UPDATE fitness_goals SET current_value = ?, progress = ?, updated_at = ? WHERE id = ?'
)
stmt.run(currentValue, progress, new Date().toISOString(), id)
return this.getFitnessGoalById(id)
}
async completeGoal(id: string): Promise<import('./types').FitnessGoal | null> {
if (!this.db) throw new Error('Database not connected')
const now = new Date()
const stmt = this.db.prepare(
'UPDATE fitness_goals SET status = ?, progress = ?, completed_date = ?, updated_at = ? WHERE id = ?'
)
stmt.run('completed', 100, now.toISOString(), now.toISOString(), id)
return this.getFitnessGoalById(id)
}
private mapRowToFitnessGoal(row: any): import('./types').FitnessGoal {
return {
id: row.id,
userId: row.user_id,
fitnessProfileId: row.fitness_profile_id,
goalType: row.goal_type,
title: row.title,
description: row.description,
targetValue: row.target_value,
currentValue: row.current_value,
unit: row.unit,
startDate: new Date(row.start_date),
targetDate: row.target_date ? new Date(row.target_date) : undefined,
completedDate: row.completed_date ? new Date(row.completed_date) : undefined,
status: row.status,
progress: row.progress,
priority: row.priority,
notes: row.notes,
createdAt: new Date(row.created_at),
updatedAt: new Date(row.updated_at)
}
}
async getDashboardStats(): Promise<{
totalUsers: number;
activeClients: number;
totalRevenue: number;
revenueGrowth: number;
}> {
if (!this.db) throw new Error('Database not connected')
// Total Users
const userCountStmt = this.db.prepare('SELECT COUNT(*) as count FROM users')
const userCount = (userCountStmt.get() as any).count
// Active Clients
const activeClientCountStmt = this.db.prepare("SELECT COUNT(*) as count FROM clients WHERE membershipStatus = 'active'")
const activeClientCount = (activeClientCountStmt.get() as any).count
// Total Revenue (assuming payments table exists, handling if it's empty)
// Note: We need to create the payments table first if it doesn't exist in createTables
// For now, returning 0 if table doesn't exist or is empty
let totalRevenue = 0
let revenueGrowth = 0
try {
const revenueStmt = this.db.prepare('SELECT SUM(amount) as total FROM payments WHERE status = "completed"')
const revenueResult = revenueStmt.get() as any
totalRevenue = revenueResult?.total || 0
} catch (e) {
// Table might not exist yet
console.warn('Payments table query failed, returning 0 revenue')
}
return {
totalUsers: userCount,
activeClients: activeClientCount,
totalRevenue,
revenueGrowth
}
}
}
+98 -2
View File
@@ -6,7 +6,7 @@ export interface User {
lastName: string;
password: string;
phone?: string;
role: "admin" | "trainer" | "client";
role: "superAdmin" | "admin" | "trainer" | "client";
createdAt: Date;
updatedAt: Date;
}
@@ -17,6 +17,7 @@ export interface Client {
membershipType: "basic" | "premium" | "vip";
membershipStatus: "active" | "inactive" | "expired";
joinDate: Date;
lastVisit?: Date;
}
export interface FitnessProfile {
@@ -30,6 +31,53 @@ export interface FitnessProfile {
exerciseHabits: string;
dietHabits: string;
medicalConditions: string;
allergies?: string;
injuries?: string;
createdAt: Date;
updatedAt: Date;
}
export interface Attendance {
id: string;
userId: string;
checkInTime: Date;
checkOutTime?: Date;
type: "gym" | "class" | "personal_training";
notes?: string;
createdAt: Date;
}
export interface Recommendation {
id: string;
userId: string;
fitnessProfileId?: string;
type: "short_term" | "medium_term" | "long_term" | "ai_plan";
content: string;
activityPlan?: string;
dietPlan?: string;
status: "pending" | "approved" | "rejected" | "completed";
createdAt: Date;
approvedAt?: Date;
approvedBy?: string;
}
export interface FitnessGoal {
id: string;
userId: string;
fitnessProfileId?: string;
goalType: "weight_target" | "strength_milestone" | "endurance_target" | "flexibility_goal" | "habit_building" | "custom";
title: string;
description?: string;
targetValue?: number;
currentValue?: number;
unit?: string;
startDate: Date;
targetDate?: Date;
completedDate?: Date;
status: "active" | "completed" | "abandoned" | "paused";
progress: number;
priority: "low" | "medium" | "high";
notes?: string;
createdAt: Date;
updatedAt: Date;
}
@@ -41,12 +89,15 @@ export interface IDatabase {
disconnect(): Promise<void>;
// User operations
createUser(user: Omit<User, "id" | "createdAt" | "updatedAt">): Promise<User>;
createUser(
user: Omit<User, "createdAt" | "updatedAt" | "id"> & { id?: string },
): Promise<User>;
getUserById(id: string): Promise<User | null>;
getUserByEmail(email: string): Promise<User | null>;
getAllUsers(): Promise<User[]>;
updateUser(id: string, updates: Partial<User>): Promise<User | null>;
deleteUser(id: string): Promise<boolean>;
migrateUserId(oldId: string, newId: string): Promise<void>;
// Client operations
createClient(client: Omit<Client, "id">): Promise<Client>;
@@ -67,6 +118,51 @@ export interface IDatabase {
updates: Partial<FitnessProfile>,
): Promise<FitnessProfile | null>;
deleteFitnessProfile(userId: string): Promise<boolean>;
// Attendance operations
checkIn(
userId: string,
type: "gym" | "class" | "personal_training",
notes?: string,
): Promise<Attendance>;
checkOut(attendanceId: string): Promise<Attendance | null>;
getAttendanceHistory(userId: string): Promise<Attendance[]>;
getAllAttendance(): Promise<Attendance[]>;
getActiveCheckIn(userId: string): Promise<Attendance | null>;
// Recommendation operations
createRecommendation(
recommendation: Omit<Recommendation, "createdAt" | "approvedAt" | "approvedBy">,
): Promise<Recommendation>;
getRecommendationsByUserId(userId: string): Promise<Recommendation[]>;
getAllRecommendations(): Promise<Recommendation[]>;
updateRecommendation(
id: string,
updates: Partial<Recommendation>,
): Promise<Recommendation | null>;
deleteRecommendation(id: string): Promise<boolean>;
// Fitness Goals operations
createFitnessGoal(
goal: Omit<FitnessGoal, "createdAt" | "updatedAt">
): Promise<FitnessGoal>;
getFitnessGoalById(id: string): Promise<FitnessGoal | null>;
getFitnessGoalsByUserId(userId: string, status?: string): Promise<FitnessGoal[]>;
updateFitnessGoal(
id: string,
updates: Partial<FitnessGoal>
): Promise<FitnessGoal | null>;
deleteFitnessGoal(id: string): Promise<boolean>;
updateGoalProgress(id: string, currentValue: number): Promise<FitnessGoal | null>;
completeGoal(id: string): Promise<FitnessGoal | null>;
// Dashboard operations
getDashboardStats(): Promise<{
totalUsers: number;
activeClients: number;
totalRevenue: number;
revenueGrowth: number; // Percentage vs last month
}>;
}
// Database configuration
+62
View File
@@ -0,0 +1,62 @@
import { currentUser } from '@clerk/nextjs/server'
import { IDatabase } from './database/types'
export async function ensureUserSynced(userId: string, db: IDatabase) {
const existingUser = await db.getUserById(userId)
if (existingUser) return existingUser
console.log('User not found in DB by ID, checking Clerk:', userId)
const clerkUser = await currentUser()
if (!clerkUser || clerkUser.id !== userId) {
// If we can't get the user from Clerk (e.g. running locally without full auth sync),
// we might want to fail gracefully or throw.
// For now, throw to be safe.
throw new Error('Could not fetch Clerk user details')
}
const email = clerkUser.emailAddresses[0]?.emailAddress
if (!email) throw new Error('User has no email')
// Check if user exists by email (e.g. seeded user)
const existingByEmail = await db.getUserByEmail(email)
if (existingByEmail) {
console.log('User found by email but ID mismatch. Migrating ID...', {
oldId: existingByEmail.id,
newId: userId
})
// Update the ID to match Clerk ID
// We need to do this manually via SQL because IDatabase interface might not expose a direct ID update method easily
// But we can use a raw query if we had access, or add a method.
// Since we don't have direct access to `db.db` here (it's hidden behind IDatabase),
// we should add a method to IDatabase or use a workaround.
// Actually, `SQLiteDatabase` is what we have at runtime.
// Let's assume we can cast it or add `updateUserId` to the interface.
// For now, let's try to update it using `updateUser` but `updateUser` usually updates fields based on ID.
// We can't update the ID itself using `updateUser(id, { id: newId })` because `updateUser` implementation filters out `id` from updates.
// We need to add a method to migrate user ID in IDatabase.
// Or, strictly for this prototype, we can delete the old user and create a new one (DATA LOSS RISK).
// But since it's a seeded super admin with no data, it's fine.
// However, if they had clients, we'd lose the link.
// Let's add `migrateUserId(oldId, newId)` to IDatabase.
await db.migrateUserId(existingByEmail.id, userId)
return db.getUserById(userId)
}
console.log('Creating new user from Clerk data:', userId)
const user = await db.createUser({
id: userId,
email,
firstName: clerkUser.firstName || '',
lastName: clerkUser.lastName || '',
password: '', // Managed by Clerk
phone: clerkUser.phoneNumbers[0]?.phoneNumber || undefined,
role: (clerkUser.publicMetadata.role as 'admin' | 'client' | 'superAdmin') || 'client'
})
return user
}
+11 -23
View File
@@ -1,26 +1,14 @@
export const formatDate = (date: Date): string => {
return new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
}).format(date)
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
export const formatCurrency = (
amount: number,
currency: string = 'USD'
): string => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
}).format(amount)
}
export const calculateDaysBetween = (startDate: Date, endDate: Date): number => {
const timeDiff = endDate.getTime() - startDate.getTime()
return Math.ceil(timeDiff / (1000 * 3600 * 24))
}
export const generateId = (): string => {
return Math.random().toString(36).substr(2, 9)
export function formatDate(date: string | Date) {
return new Date(date).toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
})
}
+1 -1
View File
@@ -5,6 +5,7 @@ const isPublicRoute = createRouteMatcher([
"/sign-in(.*)",
"/sign-up(.*)",
"/api/webhooks(.*)",
"/api/attendance(.*)",
]);
// Define routes that require authentication
@@ -16,7 +17,6 @@ const isProtectedRoute = createRouteMatcher([
"/api/users(.*)",
"/api/profile(.*)",
"/api/payments(.*)",
"/api/attendance(.*)",
"/api/notifications(.*)",
]);
+63 -8
View File
@@ -1,21 +1,76 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
'./pages/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
'./app/**/*.{ts,tsx}',
'./src/**/*.{ts,tsx}',
],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
50: '#eff6ff',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [],
plugins: [require("tailwindcss-animate")],
}
+1
View File
@@ -22,6 +22,7 @@
"name": "next"
}
],
"ignoreDeprecations": "6.0",
"baseUrl": ".",
"paths": {
"@/*": [
+3
View File
@@ -0,0 +1,3 @@
## user flow
superAdmin -> localAdmin/Gym -> localAdmin -> creates trainers -> can add users
@@ -0,0 +1,31 @@
# Values used to calculate the hash in this folder name.
# Should not depend on the absolute path of the project itself.
# - AGP: 8.11.0.
# - $NDK is the path to NDK 27.1.12297006.
# - $PROJECT is the path to the parent folder of the root Gradle build file.
# - $ABI is the ABI to be built with. The specific value doesn't contribute to the value of the hash.
# - $HASH is the hash value computed from this text.
# - $CMAKE is the path to CMake 3.22.1.
# - $NINJA is the path to Ninja.
-H/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_SYSTEM_VERSION=26
-DANDROID_PLATFORM=android-26
-DANDROID_ABI=$ABI
-DCMAKE_ANDROID_ARCH_ABI=$ABI
-DANDROID_NDK=$NDK
-DCMAKE_ANDROID_NDK=$NDK
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=$NINJA
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$PROJECT/app/build/intermediates/cxx/Debug/$HASH/obj/$ABI
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=$PROJECT/app/build/intermediates/cxx/Debug/$HASH/obj/$ABI
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_FIND_ROOT_PATH=$PROJECT/app/.cxx/Debug/$HASH/prefab/$ABI/prefab
-B$PROJECT/app/.cxx/Debug/$HASH/$ABI
-GNinja
-DPROJECT_BUILD_DIR=$PROJECT/app/build
-DPROJECT_ROOT_DIR=$PROJECT
-DREACT_ANDROID_DIR=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid
-DANDROID_STL=c++_shared
-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON
@@ -0,0 +1,27 @@
if(NOT TARGET ReactAndroid::hermestooling)
add_library(ReactAndroid::hermestooling SHARED IMPORTED)
set_target_properties(ReactAndroid::hermestooling PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/libs/android.x86/libhermestooling.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
if(NOT TARGET ReactAndroid::jsi)
add_library(ReactAndroid::jsi SHARED IMPORTED)
set_target_properties(ReactAndroid::jsi PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
if(NOT TARGET ReactAndroid::reactnative)
add_library(ReactAndroid::reactnative SHARED IMPORTED)
set_target_properties(ReactAndroid::reactnative PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 0.81.5)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,9 @@
if(NOT TARGET fbjni::fbjni)
add_library(fbjni::fbjni SHARED IMPORTED)
set_target_properties(fbjni::fbjni PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 3.22.1)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,9 @@
if(NOT TARGET hermes-engine::libhermes)
add_library(hermes-engine::libhermes SHARED IMPORTED)
set_target_properties(hermes-engine::libhermes PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/libs/android.x86/libhermes.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 0.81.5)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,27 @@
if(NOT TARGET ReactAndroid::hermestooling)
add_library(ReactAndroid::hermestooling SHARED IMPORTED)
set_target_properties(ReactAndroid::hermestooling PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/libs/android.x86_64/libhermestooling.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/hermestooling/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
if(NOT TARGET ReactAndroid::jsi)
add_library(ReactAndroid::jsi SHARED IMPORTED)
set_target_properties(ReactAndroid::jsi PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86_64/libjsi.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
if(NOT TARGET ReactAndroid::reactnative)
add_library(ReactAndroid::reactnative SHARED IMPORTED)
set_target_properties(ReactAndroid::reactnative PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86_64/libreactnative.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 0.81.5)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,9 @@
if(NOT TARGET fbjni::fbjni)
add_library(fbjni::fbjni SHARED IMPORTED)
set_target_properties(fbjni::fbjni PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86_64/libfbjni.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 3.22.1)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,9 @@
if(NOT TARGET hermes-engine::libhermes)
add_library(hermes-engine::libhermes SHARED IMPORTED)
set_target_properties(hermes-engine::libhermes PROPERTIES
IMPORTED_LOCATION "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/libs/android.x86_64/libhermes.so"
INTERFACE_INCLUDE_DIRECTORIES "/home/echo/.gradle/caches/8.14.3/transforms/f3d279cf13499f4c93e2b512ac9499e6/transformed/hermes-android-0.81.5-debug/prefab/modules/libhermes/include"
INTERFACE_LINK_LIBRARIES ""
)
endif()
@@ -0,0 +1,9 @@
set(PACKAGE_VERSION 0.81.5)
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
@@ -0,0 +1,851 @@
{
"inputs" :
[
{
"path" : "CMakeLists.txt"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineSystem.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android-legacy.toolchain.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/abis.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/platforms.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Determine.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystem.cmake.in"
},
{
"isGenerated" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeSystem.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInitialize.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Initialize.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine-C.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Determine-Compiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerId.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCompilerIdDetection.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ADSP-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Borland-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Bruce-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Compaq-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Cray-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GHS-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/HP-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IAR-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Intel-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/MSVC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PGI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PathScale-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SCO-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SDCC-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SunPro-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Watcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XL-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XLClang-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/zOS-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeFindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-FindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Determine-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerId.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCompilerIdDetection.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ADSP-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Borland-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Cray-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GHS-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/HP-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IAR-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Intel-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/MSVC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PGI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/PathScale-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SCO-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/TI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Watcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XL-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/XLClang-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeFindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-FindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeSystemSpecificInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeGenericSystem.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeInitializeConfigs.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Linux.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/UnixPaths.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-C.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/GNU.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-C.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/hooks/pre/Android-Clang.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/flags.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerABI.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitIncludeInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitLinkInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseLibraryArchitecture.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompilerABI.c"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompileFeatures.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Internal/FeatureTesting.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeLanguageInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Compiler/Clang.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Platform/Android-Clang.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCommonLanguageInclude.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompilerABI.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitIncludeInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseImplicitLinkInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeParseLibraryArchitecture.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompilerABI.cpp"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeDetermineCompileFeatures.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/Internal/FeatureTesting.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CMakeCXXCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/3.22.1-g37088a8/CMakeCXXCompiler.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactCommon/cmake-utils/react-native-flags.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/foo.cpp"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22/Modules/CheckIPOSupported/main.cpp"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid/ReactAndroidConfigVersion.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid/ReactAndroidConfig.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni/fbjniConfigVersion.cmake"
},
{
"isExternal" : true,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni/fbjniConfig.cmake"
}
],
"kind" : "cmakeFiles",
"paths" :
{
"build" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
"source" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
},
"version" :
{
"major" : 1,
"minor" : 0
}
}
@@ -0,0 +1,60 @@
{
"configurations" :
[
{
"directories" :
[
{
"build" : ".",
"jsonFile" : "directory-.-Debug-f5ebdc15457944623624.json",
"minimumCMakeVersion" :
{
"string" : "3.13"
},
"projectIndex" : 0,
"source" : ".",
"targetIndexes" :
[
0
]
}
],
"name" : "Debug",
"projects" :
[
{
"directoryIndexes" :
[
0
],
"name" : "appmodules",
"targetIndexes" :
[
0
]
}
],
"targets" :
[
{
"directoryIndex" : 0,
"id" : "appmodules::@6890427a1f51a3e7e1df",
"jsonFile" : "target-appmodules-Debug-9ef032710fe355da9383.json",
"name" : "appmodules",
"projectIndex" : 0
}
]
}
],
"kind" : "codemodel",
"paths" :
{
"build" : "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86",
"source" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
},
"version" :
{
"major" : 2,
"minor" : 3
}
}
@@ -0,0 +1,14 @@
{
"backtraceGraph" :
{
"commands" : [],
"files" : [],
"nodes" : []
},
"installers" : [],
"paths" :
{
"build" : ".",
"source" : "."
}
}
@@ -0,0 +1,92 @@
{
"cmake" :
{
"generator" :
{
"multiConfig" : false,
"name" : "Ninja"
},
"paths" :
{
"cmake" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake",
"cpack" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack",
"ctest" : "/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest",
"root" : "/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22"
},
"version" :
{
"isDirty" : false,
"major" : 3,
"minor" : 22,
"patch" : 1,
"string" : "3.22.1-g37088a8",
"suffix" : "g37088a8"
}
},
"objects" :
[
{
"jsonFile" : "codemodel-v2-d483cb7bfe026ad3a64f.json",
"kind" : "codemodel",
"version" :
{
"major" : 2,
"minor" : 3
}
},
{
"jsonFile" : "cache-v2-099ee692bdea7ed85643.json",
"kind" : "cache",
"version" :
{
"major" : 2,
"minor" : 0
}
},
{
"jsonFile" : "cmakeFiles-v1-b99aeefcc68e41c89ebf.json",
"kind" : "cmakeFiles",
"version" :
{
"major" : 1,
"minor" : 0
}
}
],
"reply" :
{
"client-agp" :
{
"cache-v2" :
{
"jsonFile" : "cache-v2-099ee692bdea7ed85643.json",
"kind" : "cache",
"version" :
{
"major" : 2,
"minor" : 0
}
},
"cmakeFiles-v1" :
{
"jsonFile" : "cmakeFiles-v1-b99aeefcc68e41c89ebf.json",
"kind" : "cmakeFiles",
"version" :
{
"major" : 1,
"minor" : 0
}
},
"codemodel-v2" :
{
"jsonFile" : "codemodel-v2-d483cb7bfe026ad3a64f.json",
"kind" : "codemodel",
"version" :
{
"major" : 2,
"minor" : 3
}
}
}
}
}
@@ -0,0 +1,226 @@
{
"artifacts" :
[
{
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86/libappmodules.so"
}
],
"backtrace" : 3,
"backtraceGraph" :
{
"commands" :
[
"add_library",
"include",
"target_link_libraries",
"target_compile_options",
"target_compile_reactnative_options",
"target_compile_definitions",
"target_include_directories"
],
"files" :
[
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake",
"CMakeLists.txt",
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactCommon/cmake-utils/react-native-flags.cmake"
],
"nodes" :
[
{
"file" : 1
},
{
"command" : 1,
"file" : 1,
"line" : 31,
"parent" : 0
},
{
"file" : 0,
"parent" : 1
},
{
"command" : 0,
"file" : 0,
"line" : 64,
"parent" : 2
},
{
"command" : 2,
"file" : 0,
"line" : 81,
"parent" : 2
},
{
"command" : 4,
"file" : 0,
"line" : 71,
"parent" : 2
},
{
"command" : 3,
"file" : 2,
"line" : 30,
"parent" : 5
},
{
"command" : 5,
"file" : 2,
"line" : 33,
"parent" : 5
},
{
"command" : 6,
"file" : 0,
"line" : 66,
"parent" : 2
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D__BIONIC_NO_PAGE_SIZE_MACRO -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fno-limit-debug-info -fPIC"
},
{
"backtrace" : 6,
"fragment" : "-Wall"
},
{
"backtrace" : 6,
"fragment" : "-Werror"
},
{
"backtrace" : 6,
"fragment" : "-fexceptions"
},
{
"backtrace" : 6,
"fragment" : "-frtti"
},
{
"backtrace" : 6,
"fragment" : "-std=c++20"
},
{
"backtrace" : 6,
"fragment" : "-DFOLLY_NO_CONFIG=1"
},
{
"backtrace" : 6,
"fragment" : "-DLOG_TAG=\\\"ReactNative\\\""
}
],
"defines" :
[
{
"backtrace" : 7,
"define" : "RN_SERIALIZABLE_STATE"
},
{
"define" : "appmodules_EXPORTS"
}
],
"includes" :
[
{
"backtrace" : 8,
"path" : "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup"
},
{
"backtrace" : 8,
"path" : "/home/echo/dev/prototype/apps/mobile/android/app/build/generated/autolinking/src/main/jni"
},
{
"backtrace" : 4,
"isSystem" : true,
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/include"
},
{
"backtrace" : 4,
"isSystem" : true,
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/include"
},
{
"backtrace" : 4,
"isSystem" : true,
"path" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/include"
}
],
"language" : "CXX",
"sourceIndexes" :
[
0
],
"sysroot" :
{
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
}
}
],
"id" : "appmodules::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-Wl,--build-id=sha1 -Wl,--no-rosegment -Wl,--no-undefined-version -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments",
"role" : "flags"
},
{
"backtrace" : 4,
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/488fe6e480efb97ec75859f6e274282f/transformed/fbjni-0.7.0/prefab/modules/fbjni/libs/android.x86/libfbjni.so",
"role" : "libraries"
},
{
"backtrace" : 4,
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/jsi/libs/android.x86/libjsi.so",
"role" : "libraries"
},
{
"backtrace" : 4,
"fragment" : "/home/echo/.gradle/caches/8.14.3/transforms/e5d515112484fe4dddc05785469cc380/transformed/react-android-0.81.5-debug/prefab/modules/reactnative/libs/android.x86/libreactnative.so",
"role" : "libraries"
},
{
"fragment" : "-latomic -lm",
"role" : "libraries"
}
],
"language" : "CXX",
"sysroot" :
{
"path" : "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
}
},
"name" : "appmodules",
"nameOnDisk" : "libappmodules.so",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Source Files",
"sourceIndexes" :
[
0
]
}
],
"sources" :
[
{
"backtrace" : 3,
"compileGroupIndex" : 0,
"path" : "OnLoad.cpp",
"sourceGroupIndex" : 0
}
],
"type" : "SHARED_LIBRARY"
}
@@ -0,0 +1,420 @@
# This is the CMakeCache file.
# For build in directory: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
# It was generated by CMake: /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//No help, variable specified on the command line.
ANDROID_ABI:UNINITIALIZED=x86
//No help, variable specified on the command line.
ANDROID_NDK:UNINITIALIZED=/home/echo/Android/Sdk/ndk/27.1.12297006
//No help, variable specified on the command line.
ANDROID_PLATFORM:UNINITIALIZED=android-26
//No help, variable specified on the command line.
ANDROID_STL:UNINITIALIZED=c++_shared
//No help, variable specified on the command line.
ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES:UNINITIALIZED=ON
//Path to a program.
CCACHE_FOUND:FILEPATH=CCACHE_FOUND-NOTFOUND
//Path to a program.
CMAKE_ADDR2LINE:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-addr2line
//No help, variable specified on the command line.
CMAKE_ANDROID_ARCH_ABI:UNINITIALIZED=x86
//No help, variable specified on the command line.
CMAKE_ANDROID_NDK:UNINITIALIZED=/home/echo/Android/Sdk/ndk/27.1.12297006
//Archiver
CMAKE_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
//Flags used by the compiler during all build types.
CMAKE_ASM_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_ASM_FLAGS_DEBUG:STRING=
//Flags used by the compiler during release builds.
CMAKE_ASM_FLAGS_RELEASE:STRING=
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Debug
//LLVM archiver
CMAKE_CXX_COMPILER_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
//Generate index for LLVM archive
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Libraries linked by default with all C++ applications.
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm
//LLVM archiver
CMAKE_C_COMPILER_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
//Generate index for LLVM archive
CMAKE_C_COMPILER_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_C_FLAGS_DEBUG:STRING=
//Flags used by the C compiler during MINSIZEREL builds.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_C_FLAGS_RELEASE:STRING=
//Flags used by the C compiler during RELWITHDEBINFO builds.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Libraries linked by default with all C applications.
CMAKE_C_STANDARD_LIBRARIES:STRING=-latomic -lm
//Path to a program.
CMAKE_DLLTOOL:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-dlltool
//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//No help, variable specified on the command line.
CMAKE_EXPORT_COMPILE_COMMANDS:UNINITIALIZED=ON
//No help, variable specified on the command line.
CMAKE_FIND_ROOT_PATH:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//No help, variable specified on the command line.
CMAKE_LIBRARY_OUTPUT_DIRECTORY:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86
//Path to a program.
CMAKE_LINKER:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld
//No help, variable specified on the command line.
CMAKE_MAKE_PROGRAM:UNINITIALIZED=/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja
//Flags used by the linker during the creation of modules.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objdump
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=appmodules
//Ranlib
CMAKE_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
//Path to a program.
CMAKE_READELF:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-readelf
//No help, variable specified on the command line.
CMAKE_RUNTIME_OUTPUT_DIRECTORY:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build/intermediates/cxx/Debug/2z472e3c/obj/x86
//Flags used by the linker during the creation of dll's.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Strip
CMAKE_STRIP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
//No help, variable specified on the command line.
CMAKE_SYSTEM_NAME:UNINITIALIZED=Android
//No help, variable specified on the command line.
CMAKE_SYSTEM_VERSION:UNINITIALIZED=26
//The CMake toolchain file
CMAKE_TOOLCHAIN_FILE:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//No help, variable specified on the command line.
PROJECT_BUILD_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android/app/build
//No help, variable specified on the command line.
PROJECT_ROOT_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/android
//No help, variable specified on the command line.
REACT_ANDROID_DIR:UNINITIALIZED=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid
//The directory containing a CMake configuration file for ReactAndroid.
ReactAndroid_DIR:PATH=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/ReactAndroid
//Value Computed by CMake
appmodules_BINARY_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
//Value Computed by CMake
appmodules_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
appmodules_SOURCE_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
//The directory containing a CMake configuration file for fbjni.
fbjni_DIR:PATH=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/prefab/x86/prefab/lib/i686-linux-android/cmake/fbjni
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_ADDR2LINE
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=22
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_STANDARD_LIBRARIES
CMAKE_C_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_DLLTOOL
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Ninja
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_READELF
CMAKE_READELF-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/usr/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
@@ -0,0 +1,72 @@
set(CMAKE_C_COMPILER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang")
set(CMAKE_C_COMPILER_ARG1 "")
set(CMAKE_C_COMPILER_ID "Clang")
set(CMAKE_C_COMPILER_VERSION "18.0.2")
set(CMAKE_C_COMPILER_VERSION_INTERNAL "")
set(CMAKE_C_COMPILER_WRAPPER "")
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "17")
set(CMAKE_C_EXTENSIONS_COMPUTED_DEFAULT "ON")
set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert;c_std_17;c_std_23")
set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes")
set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros")
set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert")
set(CMAKE_C17_COMPILE_FEATURES "c_std_17")
set(CMAKE_C23_COMPILE_FEATURES "c_std_23")
set(CMAKE_C_PLATFORM_ID "Linux")
set(CMAKE_C_SIMULATE_ID "")
set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU")
set(CMAKE_C_SIMULATE_VERSION "")
set(CMAKE_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
set(CMAKE_C_COMPILER_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
set(CMAKE_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
set(CMAKE_C_COMPILER_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
set(CMAKE_LINKER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCC )
set(CMAKE_C_COMPILER_LOADED 1)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_C_ABI_COMPILED TRUE)
set(CMAKE_C_COMPILER_ENV_VAR "CC")
set(CMAKE_C_COMPILER_ID_RUN 1)
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_C_LINKER_PREFERENCE 10)
# Save compiler ABI information.
set(CMAKE_C_SIZEOF_DATA_PTR "4")
set(CMAKE_C_COMPILER_ABI "ELF")
set(CMAKE_C_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_C_LIBRARY_ARCHITECTURE "")
if(CMAKE_C_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_C_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
endif()
if(CMAKE_C_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()
set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/include;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include")
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "-l:libunwind.a;dl;c;-l:libunwind.a;dl")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux/i386;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/26;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib")
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
@@ -0,0 +1,83 @@
set(CMAKE_CXX_COMPILER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "Clang")
set(CMAKE_CXX_COMPILER_VERSION "18.0.2")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "17")
set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23")
set(CMAKE_CXX_PLATFORM_ID "Linux")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
set(CMAKE_CXX_COMPILER_AR "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar")
set(CMAKE_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
set(CMAKE_CXX_COMPILER_RANLIB "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib")
set(CMAKE_LINKER "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCXX )
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "4")
set(CMAKE_CXX_COMPILER_ABI "ELF")
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/include;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "c++;m;-l:libunwind.a;dl;c;-l:libunwind.a;dl")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux/i386;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/26;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android;/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
@@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Linux-6.17.8-arch1-1")
set(CMAKE_HOST_SYSTEM_NAME "Linux")
set(CMAKE_HOST_SYSTEM_VERSION "6.17.8-arch1-1")
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
include("/home/echo/Android/Sdk/ndk/27.1.12297006/build/cmake/android.toolchain.cmake")
set(CMAKE_SYSTEM "Android-1")
set(CMAKE_SYSTEM_NAME "Android")
set(CMAKE_SYSTEM_VERSION "1")
set(CMAKE_SYSTEM_PROCESSOR "i686")
set(CMAKE_CROSSCOMPILING "TRUE")
set(CMAKE_SYSTEM_LOADED 1)
@@ -0,0 +1,803 @@
#ifdef __cplusplus
# error "A C++ compiler has been selected for C."
#endif
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
#if defined(__CLASSIC_C__)
/* cv-qualifiers did not exist in K&R C */
# define const
# define volatile
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_C)
# define COMPILER_ID "SunPro"
# if __SUNPRO_C >= 0x5100
/* __SUNPRO_C = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# endif
#elif defined(__HP_cc)
# define COMPILER_ID "HP"
/* __HP_cc = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
#elif defined(__DECC)
# define COMPILER_ID "Compaq"
/* __DECC_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
# define COMPILER_ID "XL"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TINYC__)
# define COMPILER_ID "TinyCC"
#elif defined(__BCC__)
# define COMPILER_ID "Bruce"
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__)
# define COMPILER_ID "GNU"
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
# define COMPILER_ID "SDCC"
# if defined(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
# else
/* SDCC = VRP */
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if !defined(__STDC__) && !defined(__clang__)
# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__)
# define C_VERSION "90"
# else
# define C_VERSION
# endif
#elif __STDC_VERSION__ > 201710L
# define C_VERSION "23"
#elif __STDC_VERSION__ >= 201710L
# define C_VERSION "17"
#elif __STDC_VERSION__ >= 201000L
# define C_VERSION "11"
#elif __STDC_VERSION__ >= 199901L
# define C_VERSION "99"
#else
# define C_VERSION "90"
#endif
const char* info_language_standard_default =
"INFO" ":" "standard_default[" C_VERSION "]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
#ifdef ID_VOID_MAIN
void main() {}
#else
# if defined(__CLASSIC_C__)
int main(argc, argv) int argc; char *argv[];
# else
int main(int argc, char* argv[])
# endif
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}
#endif
@@ -0,0 +1,791 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
/* __COMO_VERSION__ = VRR */
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
#elif defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
# if defined(__INTEL_CXX11_MODE__)
# if defined(__cpp_aggregate_nsdmi)
# define CXX_STD 201402L
# else
# define CXX_STD 201103L
# endif
# else
# define CXX_STD 199711L
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# define CXX_STD _MSVC_LANG
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_standard_default = "INFO" ":" "standard_default["
#if CXX_STD > 202002L
"23"
#elif CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
#elif CXX_STD >= 201103L
"11"
#else
"98"
#endif
"]";
const char* info_language_extensions_default = "INFO" ":" "extensions_default["
/* !defined(_MSC_VER) to exclude Clang's MSVC compatibility mode. */
#if (defined(__clang__) || defined(__GNUC__) || \
defined(__TI_COMPILER_VERSION__)) && \
!defined(__STRICT_ANSI__) && !defined(_MSC_VER)
"ON"
#else
"OFF"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_standard_default[argc];
require += info_language_extensions_default[argc];
(void)argv;
return require;
}
@@ -0,0 +1,3 @@
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/appmodules.dir
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/edit_cache.dir
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/rebuild_cache.dir
@@ -0,0 +1,23 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by CMake Version 3.22
cmake_policy(SET CMP0009 NEW)
# input_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:55 (file)
file(GLOB NEW_GLOB LIST_DIRECTORIES true "/home/echo/dev/prototype/apps/mobile/android/app/build/generated/autolinking/src/main/jni/*.cpp")
set(OLD_GLOB
)
if(NOT "${NEW_GLOB}" STREQUAL "${OLD_GLOB}")
message("-- GLOB mismatch!")
file(TOUCH_NOCREATE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/cmake.verify_globs")
endif()
# override_cpp_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:50 (file)
# input_SRC at /home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake:55 (file)
file(GLOB NEW_GLOB LIST_DIRECTORIES true "/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/*.cpp")
set(OLD_GLOB
"/home/echo/dev/prototype/apps/mobile/node_modules/react-native/ReactAndroid/cmake-utils/default-app-setup/OnLoad.cpp"
)
if(NOT "${NEW_GLOB}" STREQUAL "${OLD_GLOB}")
message("-- GLOB mismatch!")
file(TOUCH_NOCREATE "/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/cmake.verify_globs")
endif()
@@ -0,0 +1,4 @@
# ninja log v5
0 17 1764608951217248929 CMakeFiles/foo.dir/foo.cpp.o cf03112569101c0d
0 17 1764608951217248929 CMakeFiles/boo.dir/main.cpp.o a40c4ac8f9333fbb
17 47 1764608951246597989 libfoo.a 46ab43a90edc58a3
@@ -0,0 +1,281 @@
# This is the CMakeCache file.
# For build in directory: /home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
# It was generated by CMake: /home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Archiver
CMAKE_AR:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
//Flags used by the compiler during all build types.
CMAKE_ASM_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_ASM_FLAGS_DEBUG:STRING=
//Flags used by the compiler during release builds.
CMAKE_ASM_FLAGS_RELEASE:STRING=
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Libraries linked by default with all C++ applications.
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-latomic -lm
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_C_FLAGS_DEBUG:STRING=
//Flags used by the compiler during release builds.
CMAKE_C_FLAGS_RELEASE:STRING=
//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//No help, variable specified on the command line.
CMAKE_INTERPROCEDURAL_OPTIMIZATION:UNINITIALIZED=ON
//make program
CMAKE_MAKE_PROGRAM:FILEPATH=/home/echo/Android/Sdk/cmake/3.22.1/bin/ninja
//Flags used by the linker during the creation of modules.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=lto-test
//Ranlib
CMAKE_RANLIB:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
//Flags used by the linker during the creation of dll's.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Strip
CMAKE_STRIP:FILEPATH=/home/echo/Android/Sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=ON
//Value Computed by CMake
lto-test_BINARY_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
//Value Computed by CMake
lto-test_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
lto-test_SOURCE_DIR:STATIC=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src
########################
# INTERNAL cache entries
########################
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=22
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Ninja
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/src
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/home/echo/Android/Sdk/cmake/3.22.1/share/cmake-3.22
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
CMAKE_SUPPRESS_DEVELOPER_WARNINGS:INTERNAL=FALSE
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
@@ -0,0 +1,4 @@
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/foo.dir
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/boo.dir
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/edit_cache.dir
/home/echo/dev/prototype/apps/mobile/android/app/.cxx/Debug/2z472e3c/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/rebuild_cache.dir
Loaded 100 of 307 files, more files were not shown because too many files have changed in this diff. Show more