import { createContext, useCallback, useContext, useMemo, useState, type ReactNode, } from 'react'; type Language = 'en' | 'th'; type Params = Record; const strings: Record> = { en: { 'tabs.home': 'Home', 'tabs.explore': 'Explore', 'tabs.onnx': 'Leaf Scan', 'tabs.setup': 'Setup', 'tabs.blog': 'Blog', 'tabs.tasks': 'Tasks', 'tabs.fields': 'Fields', 'tabs.logbook': 'Logbook', 'tabs.taskHistory': 'History', 'setup.title': 'User Setup', 'setup.profile': 'Profile', 'setup.loading': 'Loading...', 'setup.loaded': 'Loaded saved profile.', 'setup.none': 'No profile yet. Fill the form and save.', 'setup.saving': 'Saving...', 'setup.saved': 'Saved locally.', 'setup.photo': 'Profile photo', 'setup.noPhoto': 'No photo selected.', 'setup.uploadPhoto': 'Upload photo', 'setup.exportTitle': 'Export data', 'setup.exportHint': 'Download your local data as a CSV file.', 'setup.exportButton': 'Export data', 'setup.exported': 'Exported data.', 'setup.exportError': 'Export failed.', 'setup.name': 'Name', 'setup.farmName': 'Farm name', 'setup.location': 'Location', 'setup.save': 'Save locally', 'setup.saveIndicator': 'Saved!', 'setup.language': 'Language', 'setup.lang.en': 'English', 'setup.lang.th': 'Thai', 'setup.currency': 'Default currency', 'setup.currencyPlaceholder': 'e.g. THB', 'setup.currency.thb': 'THB', 'setup.currency.usd': 'USD', 'setup.currency.eur': 'EUR', 'setup.currency.jpy': 'JPY', 'setup.demoTitle': 'Demo Data', 'setup.demoHint': 'Insert sample fields, crops, observations, and task history.', 'setup.demoButton': 'Insert demo data', 'setup.demoInserting': 'Inserting demo data...', 'setup.demoInserted': 'Demo data inserted.', 'setup.demoExists': 'Demo data already exists.', 'setup.demoError': 'Demo insert failed.', 'setup.demoClearButton': 'Clear demo data', 'setup.demoClearing': 'Clearing demo data...', 'setup.demoCleared': 'Demo data cleared.', 'setup.demoClearError': 'Clear demo failed.', 'setup.demoClearedUndo': 'Demo data cleared.', 'setup.demoUndo': 'Undo', 'setup.demoUndoDone': 'Demo data restored.', 'setup.demoUndoError': 'Undo failed.', 'onnx.title': 'Leaf Classifier', 'onnx.howTitle': 'How to use the ONNX model', 'onnx.howBody': 'This page loads the PlantVillage MobileNetV3-Small model and runs inference on a 224x224 RGB tensor. The input is normalized to 0..1 per channel.', 'onnx.sampleTitle': 'Sample code', 'onnx.testTitle': 'Test the model', 'onnx.pickImage': 'Pick image', 'onnx.runModel': 'Run model', 'onnx.status.pick': 'Pick an image to run the model.', 'onnx.status.ready': 'Ready. Tap "Run model" to classify.', 'onnx.status.preprocessing': 'Preprocessing image...', 'onnx.status.running': 'Running PlantVillage model...', 'onnx.status.done': 'Done.', 'onnx.status.nativeMissing': 'ONNX runtime not available. Use a dev build.', 'onnx.topPredictions': 'Top predictions', 'blog.title': 'Blog Posts', 'blog.loading': 'Loading posts...', 'blog.error': 'Failed to load posts.', 'blog.empty': 'No posts found.', 'blog.loadMore': 'Load more', 'blog.loadingMore': 'Loading more...', 'blog.language': 'Language', 'blog.lang.en': 'English', 'blog.lang.th': 'Thai', 'blog.lang.ja': 'Japanese', 'blog.lang.zh': 'Chinese', 'home.badge': 'Smartfarming Lite', 'home.title': 'Track fields, crops, and observations without leaving the farm.', 'home.subtitle': 'Offline-first records for daily work, photos, and crop history.', 'home.openLogbook': 'Open Logbook', 'home.todayTasks': "Today’s Tasks", 'home.quickActions': 'Quick Actions', 'home.fields': 'Fields', 'home.fieldsHint': 'Add area, notes, photos.', 'home.crops': 'Crops', 'home.cropsHint': 'Planting and harvest dates.', 'home.observations': 'Observations', 'home.observationsHint': 'Notes, severity, images.', 'home.onnx': 'Leaf Scan', 'home.onnxHint': 'Run leaf classifier.', 'home.harvests': 'Harvests', 'home.harvestsHint': 'Yield and harvest records.', 'home.sales': 'Sales', 'home.salesHint': 'Sales records and buyers.', 'home.costs': 'Costs', 'home.costsHint': 'Record expenses.', 'home.todayTitle': 'Today', 'home.todayCardTitle': 'Log your field routine', 'home.todayCardBody': 'Capture scouting notes, attach photos, and keep a clean history for the next visit.', 'home.openTasks': 'Open Tasks', 'home.taskHistory': 'Task History', 'home.learnAnalyze': 'Learn & Analyze', 'home.blogs': 'Blogs', 'home.blogsHint': 'Latest smart farming posts.', 'home.profile': 'Profile', 'home.profileHint': 'Farm info and language.', 'home.count.tasks': 'Tasks', 'home.count.history': 'History', 'tasks.title': 'Daily Tasks', 'tasks.subtitle': 'Log today’s field routine.', 'tasks.loading': 'Loading tasks...', 'tasks.empty': 'No tasks configured yet.', 'tasks.pending': 'Pending', 'tasks.done': 'Done', 'tasks.complete': 'Mark done', 'tasks.undo': 'Undo', 'tasks.notePlaceholder': 'Add notes for today...', 'tasks.photo': 'Task photo', 'tasks.pickPhoto': 'Pick photo', 'tasks.takePhoto': 'Take photo', 'tasks.cameraDenied': 'Camera permission denied.', 'tasks.cameraError': 'Camera is not available.', 'tasks.historyTitle': 'Task History', 'tasks.historyEmpty': 'No task history yet.', 'tasks.back': 'Back to Tasks', 'tasks.default.fieldCheck': 'Field check-in', 'tasks.default.fieldCheckDesc': 'Quick field condition and notes.', 'tasks.default.scouting': 'Pest/Disease scouting', 'tasks.default.scoutingDesc': 'Inspect leaves and record severity.', 'tasks.default.sensors': 'Sensor readings', 'tasks.default.sensorsDesc': 'Log soil moisture or weather snapshot.', 'fields.title': 'Fields', 'fields.loading': 'Loading fields...', 'fields.empty': 'No fields yet.', 'fields.nameRequired': 'Field name is required.', 'fields.areaInvalid': 'Area must be a number.', 'fields.saved': 'Saved.', 'fields.name': 'Field name', 'fields.area': 'Area (ha)', 'fields.areaPlaceholder': 'e.g. 1.5', 'fields.notes': 'Notes', 'fields.notesPlaceholder': 'Soil, irrigation, landmarks...', 'fields.save': 'Save field', 'fields.update': 'Update field', 'fields.cancel': 'Cancel', 'fields.edit': 'Edit', 'fields.delete': 'Delete', 'fields.deleteTitle': 'Delete field?', 'fields.deleteMessage': 'This action cannot be undone.', 'fields.new': 'New field', 'fields.unnamed': 'Unnamed field', 'fields.areaLabel': 'Area:', 'fields.photo': 'Field photo', 'fields.pickPhoto': 'Pick photo', 'fields.takePhoto': 'Take photo', 'fields.noPhoto': 'No photo selected.', 'fields.updatedAt': 'Updated:', 'logbook.title': 'Logbook', 'logbook.subtitle': 'Manage your core records.', 'logbook.fields': 'Fields', 'logbook.fieldsHint': 'Land area, notes, boundaries.', 'logbook.observations': 'Observations', 'logbook.observationsHint': 'Scouting notes and severity.', 'logbook.crops': 'Crops', 'logbook.cropsHint': 'Crop info by field.', 'logbook.tasks': 'Daily Tasks', 'logbook.tasksHint': 'Notes, photos, status.', 'logbook.history': 'Task History', 'logbook.historyHint': 'Completed entries by date.', 'logbook.harvests': 'Harvests', 'logbook.harvestsHint': 'Yield and harvest details.', 'logbook.sales': 'Sales', 'logbook.salesHint': 'Sales records and buyers.', 'logbook.costs': 'Costs', 'logbook.costsHint': 'Expenses and receipts.', 'observations.title': 'Observations', 'observations.loading': 'Loading observations...', 'observations.empty': 'No observations yet.', 'observations.saved': 'Saved.', 'observations.field': 'Field', 'observations.crop': 'Crop', 'observations.type': 'Type', 'observations.note': 'Note', 'observations.severity': 'Severity', 'observations.severityLabel': 'Severity:', 'observations.selectField': 'Select field', 'observations.selectCrop': 'Select crop', 'observations.typePlaceholder': 'e.g. scouting', 'observations.notePlaceholder': 'What did you observe?', 'observations.severityPlaceholder': '0-10', 'observations.fieldRequired': 'Field is required.', 'observations.severityInvalid': 'Severity must be a number.', 'observations.delete': 'Delete', 'observations.noField': 'No field', 'observations.noCrop': 'No crop', 'observations.untitled': 'Observation', 'observations.save': 'Save observation', 'observations.new': 'New observation', 'observations.cancel': 'Cancel', 'observations.edit': 'Edit observation', 'observations.update': 'Update observation', 'observations.photo': 'Observation photo', 'observations.pickPhoto': 'Pick photo', 'observations.takePhoto': 'Take photo', 'observations.noPhoto': 'No photo selected.', 'harvests.title': 'Harvest Records', 'harvests.loading': 'Loading harvest records...', 'harvests.empty': 'No harvest records yet.', 'harvests.saved': 'Saved.', 'harvests.new': 'New harvest', 'harvests.field': 'Field', 'harvests.crop': 'Crop', 'harvests.selectField': 'Select field', 'harvests.selectCrop': 'Select crop', 'harvests.date': 'Harvest date', 'harvests.datePlaceholder': 'YYYY-MM-DD', 'harvests.quantity': 'Quantity', 'harvests.quantityPlaceholder': 'e.g. 120', 'harvests.unit': 'Unit', 'harvests.unitPlaceholder': 'kg', 'harvests.notes': 'Notes', 'harvests.notesPlaceholder': 'Quality, weather, labor notes...', 'harvests.photo': 'Harvest photo', 'harvests.pickPhoto': 'Pick photo', 'harvests.takePhoto': 'Take photo', 'harvests.noPhoto': 'No photo selected.', 'harvests.fieldRequired': 'Field is required.', 'harvests.cropRequired': 'Crop is required.', 'harvests.quantityInvalid': 'Quantity must be a number.', 'harvests.delete': 'Delete', 'harvests.deleteTitle': 'Delete harvest record?', 'harvests.deleteMessage': 'This action cannot be undone.', 'harvests.cancel': 'Cancel', 'harvests.save': 'Save harvest', 'harvests.untitled': 'Harvest', 'harvests.noField': 'No field', 'harvests.noCrop': 'No crop', 'harvests.edit': 'Edit harvest', 'harvests.update': 'Update harvest', 'units.kg': 'kg', 'units.g': 'g', 'units.ton': 'ton', 'units.pcs': 'pcs', 'sales.title': 'Sales Records', 'sales.loading': 'Loading sales records...', 'sales.empty': 'No sales records yet.', 'sales.saved': 'Saved.', 'sales.new': 'New sale', 'sales.field': 'Field', 'sales.crop': 'Crop', 'sales.harvest': 'Harvest (optional)', 'sales.selectField': 'Select field', 'sales.selectCrop': 'Select crop', 'sales.selectHarvest': 'Select harvest', 'sales.noHarvest': 'No harvest records', 'sales.date': 'Sale date', 'sales.datePlaceholder': 'YYYY-MM-DD', 'sales.quantity': 'Quantity', 'sales.quantityPlaceholder': 'e.g. 50', 'sales.unit': 'Unit', 'sales.unitPlaceholder': 'kg', 'sales.price': 'Price', 'sales.pricePlaceholder': 'e.g. 35', 'sales.priceLabel': 'Price:', 'sales.buyer': 'Buyer', 'sales.buyerPlaceholder': 'e.g. Local market', 'sales.notes': 'Notes', 'sales.notesPlaceholder': 'Payment, transport, quality...', 'sales.fieldRequired': 'Field is required.', 'sales.cropRequired': 'Crop is required.', 'sales.quantityInvalid': 'Quantity must be a number.', 'sales.delete': 'Delete', 'sales.deleteTitle': 'Delete sales record?', 'sales.deleteMessage': 'This action cannot be undone.', 'sales.cancel': 'Cancel', 'sales.save': 'Save sale', 'sales.untitled': 'Sale', 'sales.noField': 'No field', 'sales.noCrop': 'No crop', 'sales.edit': 'Edit sale', 'sales.update': 'Update sale', 'costs.title': 'Cost Records', 'costs.loading': 'Loading costs...', 'costs.empty': 'No cost records yet.', 'costs.saved': 'Saved.', 'costs.new': 'New cost', 'costs.field': 'Field', 'costs.crop': 'Crop (optional)', 'costs.selectField': 'Select field', 'costs.selectCrop': 'Select crop', 'costs.category': 'Category', 'costs.category.seed': 'Seed', 'costs.category.fertilizer': 'Fertilizer', 'costs.category.labor': 'Labor', 'costs.category.fuel': 'Fuel', 'costs.category.equipment': 'Equipment', 'costs.category.transport': 'Transport', 'costs.category.misc': 'Misc', 'costs.categoryPlaceholder': 'e.g. Seed', 'costs.amount': 'Amount', 'costs.amountPlaceholder': 'e.g. 1200', 'costs.vendor': 'Vendor', 'costs.vendorPlaceholder': 'e.g. Local supplier', 'costs.date': 'Date', 'costs.datePlaceholder': 'YYYY-MM-DD', 'costs.notes': 'Notes', 'costs.notesPlaceholder': 'Receipt, usage, purpose...', 'costs.photo': 'Receipt photo', 'costs.pickPhoto': 'Pick photo', 'costs.takePhoto': 'Take photo', 'costs.noPhoto': 'No photo selected.', 'costs.fieldRequired': 'Field is required.', 'costs.amountInvalid': 'Amount must be a number.', 'costs.delete': 'Delete', 'costs.deleteTitle': 'Delete cost record?', 'costs.deleteMessage': 'This action cannot be undone.', 'costs.cancel': 'Cancel', 'costs.save': 'Save cost', 'costs.edit': 'Edit cost', 'costs.update': 'Update cost', 'costs.untitled': 'Cost', 'costs.noField': 'No field', 'costs.noCrop': 'No crop', 'units.kg': 'กก.', 'units.g': 'กรัม', 'units.ton': 'ตัน', 'units.pcs': 'ชิ้น', 'demo.field.north': 'North Field', 'demo.field.northNote': 'Loamy soil · drip irrigation', 'demo.field.river': 'River Plot', 'demo.field.riverNote': 'Lowland area near canal', 'demo.field.greenhouse': 'Greenhouse', 'demo.field.greenhouseNote': 'Shaded beds, irrigation daily', 'demo.field.orchard': 'Orchard Block', 'demo.field.orchardNote': 'Raised rows, windbreak on east side', 'demo.field.terrace': 'Terrace Plot', 'demo.field.terraceNote': 'Stepped slope with drip lines', 'demo.crop.tomato': 'Tomato', 'demo.crop.tomatoVariety': 'Cherry', 'demo.crop.rice': 'Rice', 'demo.crop.riceVariety': 'Jasmine', 'demo.crop.lettuce': 'Lettuce', 'demo.crop.lettuceVariety': 'Butterhead', 'demo.crop.chili': 'Chili', 'demo.crop.chiliVariety': 'Bird’s eye', 'demo.crop.cabbage': 'Cabbage', 'demo.crop.cabbageVariety': 'Green cabbage', 'demo.observation.scoutingNote': 'Early leaf spot found on edge rows.', 'demo.observation.diseaseNote': 'Disease patches visible after rain.', 'demo.observation.irrigationNote': 'Adjusted irrigation timing to evening.', 'demo.observation.pestNote': 'Aphids spotted on new growth.', 'demo.observation.nutrientNote': 'Lower leaves pale, applied foliar feed.', 'demo.task.note': 'Completed as scheduled.', 'demo.task.note2': 'Followed standard checklist.', 'demo.task.note3': 'Checked equipment and logged readings.', 'demo.harvest.note1': 'Morning harvest, good quality.', 'demo.harvest.note2': 'Harvested after light rain.', 'demo.harvest.note3': 'Sorted by size for market.', 'demo.sale.buyer1': 'Local market', 'demo.sale.buyer2': 'Wholesale buyer', 'demo.sale.buyer3': 'Restaurant partner', 'demo.sale.note1': 'Delivered same day.', 'demo.sale.note2': 'Paid in full.', 'demo.sale.note3': 'Requested weekly supply.', 'demo.cost.vendor1': 'Agro supply', 'demo.cost.vendor2': 'Fertilizer store', 'demo.cost.vendor3': 'Labor crew', 'demo.cost.note1': 'Tomato seeds and trays.', 'demo.cost.note2': 'Base fertilizer for rice plot.', 'demo.cost.note3': 'Harvest helpers (half day).', 'observations.type.scouting': 'Scouting', 'observations.type.pest': 'Pest', 'observations.type.disease': 'Disease', 'observations.type.irrigation': 'Irrigation', 'observations.type.weeds': 'Weeds', 'observations.type.nutrients': 'Nutrients', 'crops.title': 'Crops', 'crops.loading': 'Loading crops...', 'crops.empty': 'No crops yet.', 'crops.saved': 'Saved.', 'crops.field': 'Field', 'crops.selectField': 'Select field', 'crops.name': 'Crop name', 'crops.variety': 'Variety', 'crops.planting': 'Planting date', 'crops.harvest': 'Expected harvest', 'crops.namePlaceholder': 'e.g. Tomato', 'crops.varietyPlaceholder': 'e.g. Cherry', 'crops.plantingPlaceholder': 'YYYY-MM-DD', 'crops.harvestPlaceholder': 'YYYY-MM-DD', 'crops.fieldRequired': 'Field is required.', 'crops.nameRequired': 'Crop name is required.', 'crops.delete': 'Delete', 'crops.deleteTitle': 'Delete crop?', 'crops.deleteMessage': 'This action cannot be undone.', 'crops.noField': 'No field', 'crops.untitled': 'Crop', 'crops.plantingLabel': 'Planted:', 'crops.harvestLabel': 'Harvest:', 'crops.save': 'Save crop', 'crops.new': 'New crop', 'crops.photo': 'Crop photo', 'crops.pickPhoto': 'Pick photo', 'crops.takePhoto': 'Take photo', 'crops.noPhoto': 'No photo selected.', 'crops.today': 'Today', 'crops.done': 'Done', 'crops.edit': 'Edit crop', 'crops.update': 'Update crop', 'crops.cancel': 'Cancel', }, th: { 'tabs.home': 'หน้าแรก', 'tabs.explore': 'สำรวจ', 'tabs.onnx': 'สแกนใบ', 'tabs.setup': 'ตั้งค่า', 'tabs.blog': 'บล็อก', 'tabs.tasks': 'งานประจำวัน', 'tabs.fields': 'แปลง', 'tabs.logbook': 'บันทึก', 'tabs.taskHistory': 'ประวัติ', 'setup.title': 'ตั้งค่าผู้ใช้', 'setup.profile': 'โปรไฟล์', 'setup.loading': 'กำลังโหลด...', 'setup.loaded': 'โหลดโปรไฟล์ที่บันทึกไว้แล้ว', 'setup.none': 'ยังไม่มีโปรไฟล์ กรอกข้อมูลแล้วกดบันทึก', 'setup.saving': 'กำลังบันทึก...', 'setup.saved': 'บันทึกไว้ในเครื่องแล้ว', 'setup.photo': 'รูปโปรไฟล์', 'setup.noPhoto': 'ยังไม่ได้เลือกรูป', 'setup.uploadPhoto': 'อัปโหลดรูป', 'setup.exportTitle': 'ส่งออกข้อมูล', 'setup.exportHint': 'ดาวน์โหลดข้อมูลในเครื่องเป็นไฟล์ CSV', 'setup.exportButton': 'ส่งออกข้อมูล', 'setup.exported': 'ส่งออกข้อมูลแล้ว', 'setup.exportError': 'ส่งออกข้อมูลไม่สำเร็จ', 'setup.name': 'ชื่อ', 'setup.farmName': 'ชื่อฟาร์ม', 'setup.location': 'ที่ตั้ง', 'setup.save': 'บันทึกในเครื่อง', 'setup.saveIndicator': 'บันทึกแล้ว', 'setup.language': 'ภาษา', 'setup.lang.en': 'English', 'setup.lang.th': 'ไทย', 'setup.currency': 'สกุลเงินเริ่มต้น', 'setup.currencyPlaceholder': 'เช่น THB', 'setup.currency.thb': 'บาท (THB)', 'setup.currency.usd': 'ดอลลาร์ (USD)', 'setup.currency.eur': 'ยูโร (EUR)', 'setup.currency.jpy': 'เยน (JPY)', 'setup.demoTitle': 'ข้อมูลตัวอย่าง', 'setup.demoHint': 'เพิ่มข้อมูลตัวอย่าง: แปลง พืช บันทึกสำรวจ และประวัติงาน', 'setup.demoButton': 'เพิ่มข้อมูลตัวอย่าง', 'setup.demoInserting': 'กำลังเพิ่มข้อมูลตัวอย่าง...', 'setup.demoInserted': 'เพิ่มข้อมูลตัวอย่างแล้ว', 'setup.demoExists': 'มีข้อมูลอยู่แล้ว', 'setup.demoError': 'เพิ่มข้อมูลไม่สำเร็จ', 'setup.demoClearButton': 'ลบข้อมูลตัวอย่าง', 'setup.demoClearing': 'กำลังลบข้อมูลตัวอย่าง...', 'setup.demoCleared': 'ลบข้อมูลตัวอย่างแล้ว', 'setup.demoClearError': 'ลบข้อมูลไม่สำเร็จ', 'setup.demoClearedUndo': 'ลบข้อมูลตัวอย่างแล้ว', 'setup.demoUndo': 'ย้อนกลับ', 'setup.demoUndoDone': 'กู้คืนข้อมูลตัวอย่างแล้ว', 'setup.demoUndoError': 'ย้อนกลับไม่สำเร็จ', 'onnx.title': 'จำแนกโรคใบพืช', 'onnx.howTitle': 'วิธีใช้โมเดล ONNX', 'onnx.howBody': 'หน้านี้โหลดโมเดล PlantVillage MobileNetV3-Small และรันอินเฟอเรนซ์ด้วยเทนเซอร์ RGB ขนาด 224x224 อินพุตถูกทำให้อยู่ในช่วง 0..1 ต่อช่องสี', 'onnx.sampleTitle': 'ตัวอย่างโค้ด', 'onnx.testTitle': 'ทดสอบโมเดล', 'onnx.pickImage': 'เลือกรูป', 'onnx.runModel': 'รันโมเดล', 'onnx.status.pick': 'เลือกรูปเพื่อรันโมเดล', 'onnx.status.ready': 'พร้อมแล้ว กด "รันโมเดล" เพื่อจำแนก', 'onnx.status.preprocessing': 'กำลังเตรียมรูป...', 'onnx.status.running': 'กำลังรันโมเดล PlantVillage...', 'onnx.status.done': 'เสร็จแล้ว', 'onnx.status.nativeMissing': 'ไม่พบ ONNX runtime โปรดใช้ dev build', 'onnx.topPredictions': 'ผลลัพธ์สูงสุด', 'blog.title': 'บทความล่าสุด', 'blog.loading': 'กำลังโหลดบทความ...', 'blog.error': 'โหลดบทความไม่สำเร็จ', 'blog.empty': 'ไม่พบบทความ', 'blog.loadMore': 'โหลดเพิ่มเติม', 'blog.loadingMore': 'กำลังโหลดเพิ่มเติม...', 'blog.language': 'ภาษา', 'blog.lang.en': 'English', 'blog.lang.th': 'ไทย', 'blog.lang.ja': 'ญี่ปุ่น', 'blog.lang.zh': 'จีน', 'home.badge': 'สมาร์ทฟาร์มมิ่ง ไลต์', 'home.title': 'ติดตามแปลง พืช และบันทึกสำรวจได้ทันทีในฟาร์ม', 'home.subtitle': 'บันทึกแบบออฟไลน์สำหรับงานประจำวัน รูปภาพ และประวัติพืช', 'home.openLogbook': 'เปิดบันทึก', 'home.todayTasks': 'งานวันนี้', 'home.quickActions': 'ทางลัด', 'home.fields': 'แปลง', 'home.fieldsHint': 'เพิ่มพื้นที่ บันทึก และรูปภาพ', 'home.crops': 'พืช', 'home.cropsHint': 'วันที่ปลูกและเก็บเกี่ยว', 'home.observations': 'บันทึกสำรวจ', 'home.observationsHint': 'บันทึก ความรุนแรง และรูปภาพ', 'home.onnx': 'สแกนใบ', 'home.onnxHint': 'รันโมเดลจำแนกใบพืช', 'home.harvests': 'เก็บเกี่ยว', 'home.harvestsHint': 'ผลผลิตและบันทึกการเก็บเกี่ยว', 'home.sales': 'ขายผลผลิต', 'home.salesHint': 'บันทึกการขายและผู้ซื้อ', 'home.costs': 'ต้นทุน', 'home.costsHint': 'บันทึกค่าใช้จ่าย', 'home.todayTitle': 'วันนี้', 'home.todayCardTitle': 'บันทึกงานประจำแปลง', 'home.todayCardBody': 'บันทึกการสำรวจ ถ่ายรูป และเก็บประวัติให้พร้อมสำหรับครั้งถัดไป', 'home.openTasks': 'เปิดงานประจำวัน', 'home.taskHistory': 'ประวัติงาน', 'home.learnAnalyze': 'เรียนรู้และวิเคราะห์', 'home.blogs': 'บล็อก', 'home.blogsHint': 'บทความสมาร์ทฟาร์มมิ่งล่าสุด', 'home.profile': 'โปรไฟล์', 'home.profileHint': 'ข้อมูลฟาร์มและภาษา', 'home.count.tasks': 'งาน', 'home.count.history': 'ประวัติ', 'tasks.title': 'งานประจำวัน', 'tasks.subtitle': 'บันทึกงานประจำวันของแปลงวันนี้', 'tasks.loading': 'กำลังโหลดงาน...', 'tasks.empty': 'ยังไม่มีงานที่ตั้งไว้', 'tasks.pending': 'รอดำเนินการ', 'tasks.done': 'เสร็จแล้ว', 'tasks.complete': 'ทำเสร็จแล้ว', 'tasks.undo': 'ย้อนกลับ', 'tasks.notePlaceholder': 'เพิ่มบันทึกสำหรับวันนี้...', 'tasks.photo': 'รูปงาน', 'tasks.pickPhoto': 'เลือกรูป', 'tasks.takePhoto': 'ถ่ายรูป', 'tasks.cameraDenied': 'ไม่ได้รับอนุญาตให้ใช้กล้อง', 'tasks.cameraError': 'ไม่สามารถใช้งานกล้องได้', 'tasks.historyTitle': 'ประวัติงานประจำวัน', 'tasks.historyEmpty': 'ยังไม่มีประวัติงาน', 'tasks.back': 'กลับไปงานประจำวัน', 'tasks.default.fieldCheck': 'ตรวจแปลง', 'tasks.default.fieldCheckDesc': 'เช็คสภาพแปลงและบันทึกสั้น ๆ', 'tasks.default.scouting': 'สำรวจแมลง/โรค', 'tasks.default.scoutingDesc': 'ตรวจใบและบันทึกความรุนแรง', 'tasks.default.sensors': 'อ่านค่าจากเซนเซอร์', 'tasks.default.sensorsDesc': 'บันทึกความชื้นดินหรือสภาพอากาศ', 'fields.title': 'แปลง', 'fields.loading': 'กำลังโหลดแปลง...', 'fields.empty': 'ยังไม่มีแปลง', 'fields.nameRequired': 'ต้องระบุชื่อแปลง', 'fields.areaInvalid': 'พื้นที่ต้องเป็นตัวเลข', 'fields.saved': 'บันทึกแล้ว', 'fields.name': 'ชื่อแปลง', 'fields.area': 'พื้นที่ (ไร่)', 'fields.areaPlaceholder': 'เช่น 1.5', 'fields.notes': 'บันทึก', 'fields.notesPlaceholder': 'ดิน น้ำ จุดสังเกต...', 'fields.save': 'บันทึกแปลง', 'fields.update': 'อัปเดตแปลง', 'fields.cancel': 'ยกเลิก', 'fields.edit': 'แก้ไข', 'fields.delete': 'ลบ', 'fields.deleteTitle': 'ลบแปลงนี้ไหม?', 'fields.deleteMessage': 'การลบไม่สามารถย้อนกลับได้', 'fields.new': 'เพิ่มแปลง', 'fields.unnamed': 'แปลงไม่มีชื่อ', 'fields.areaLabel': 'พื้นที่:', 'fields.photo': 'รูปแปลง', 'fields.pickPhoto': 'เลือกรูป', 'fields.takePhoto': 'ถ่ายรูป', 'fields.noPhoto': 'ยังไม่ได้เลือกรูป', 'fields.updatedAt': 'อัปเดตเมื่อ:', 'logbook.title': 'บันทึก', 'logbook.subtitle': 'จัดการข้อมูลหลักของคุณ', 'logbook.fields': 'แปลง', 'logbook.fieldsHint': 'พื้นที่ บันทึก ขอบเขต', 'logbook.observations': 'บันทึกสำรวจ', 'logbook.observationsHint': 'บันทึกสำรวจและความรุนแรง', 'logbook.crops': 'พืช', 'logbook.cropsHint': 'ข้อมูลพืชตามแปลง', 'logbook.tasks': 'งานประจำวัน', 'logbook.tasksHint': 'บันทึก รูปภาพ สถานะ', 'logbook.history': 'ประวัติงาน', 'logbook.historyHint': 'รายการที่เสร็จแล้วตามวันที่', 'logbook.harvests': 'เก็บเกี่ยว', 'logbook.harvestsHint': 'ผลผลิตและรายละเอียดการเก็บเกี่ยว', 'logbook.sales': 'ขายผลผลิต', 'logbook.salesHint': 'บันทึกการขายและผู้ซื้อ', 'logbook.costs': 'ต้นทุน', 'logbook.costsHint': 'ค่าใช้จ่ายและใบเสร็จ', 'observations.title': 'บันทึกสำรวจ', 'observations.loading': 'กำลังโหลดบันทึก...', 'observations.empty': 'ยังไม่มีบันทึก', 'observations.saved': 'บันทึกแล้ว', 'observations.field': 'แปลง', 'observations.crop': 'พืช', 'observations.type': 'ประเภท', 'observations.note': 'บันทึก', 'observations.severity': 'ความรุนแรง', 'observations.severityLabel': 'ความรุนแรง:', 'observations.selectField': 'เลือกแปลง', 'observations.selectCrop': 'เลือกพืช', 'observations.typePlaceholder': 'เช่น สำรวจโรค', 'observations.notePlaceholder': 'สังเกตอะไรบ้าง?', 'observations.severityPlaceholder': '0-10', 'observations.fieldRequired': 'ต้องเลือกแปลง', 'observations.severityInvalid': 'ความรุนแรงต้องเป็นตัวเลข', 'observations.delete': 'ลบ', 'observations.noField': 'ไม่มีแปลง', 'observations.noCrop': 'ไม่มีพืช', 'observations.untitled': 'บันทึกสำรวจ', 'observations.save': 'บันทึกข้อมูล', 'observations.new': 'เพิ่มบันทึก', 'observations.cancel': 'ยกเลิก', 'observations.edit': 'แก้ไขบันทึก', 'observations.update': 'อัปเดตบันทึก', 'observations.photo': 'รูปประกอบ', 'observations.pickPhoto': 'เลือกรูป', 'observations.takePhoto': 'ถ่ายรูป', 'observations.noPhoto': 'ยังไม่ได้เลือกรูป', 'harvests.title': 'บันทึกการเก็บเกี่ยว', 'harvests.loading': 'กำลังโหลดการเก็บเกี่ยว...', 'harvests.empty': 'ยังไม่มีบันทึกการเก็บเกี่ยว', 'harvests.saved': 'บันทึกแล้ว', 'harvests.new': 'เพิ่มการเก็บเกี่ยว', 'harvests.field': 'แปลง', 'harvests.crop': 'พืช', 'harvests.selectField': 'เลือกแปลง', 'harvests.selectCrop': 'เลือกพืช', 'harvests.date': 'วันที่เก็บเกี่ยว', 'harvests.datePlaceholder': 'YYYY-MM-DD', 'harvests.quantity': 'ปริมาณ', 'harvests.quantityPlaceholder': 'เช่น 120', 'harvests.unit': 'หน่วย', 'harvests.unitPlaceholder': 'กก.', 'harvests.notes': 'บันทึก', 'harvests.notesPlaceholder': 'คุณภาพ สภาพอากาศ แรงงาน...', 'harvests.photo': 'รูปการเก็บเกี่ยว', 'harvests.pickPhoto': 'เลือกรูป', 'harvests.takePhoto': 'ถ่ายรูป', 'harvests.noPhoto': 'ยังไม่ได้เลือกรูป', 'harvests.fieldRequired': 'ต้องเลือกแปลง', 'harvests.cropRequired': 'ต้องเลือกพืช', 'harvests.quantityInvalid': 'ปริมาณต้องเป็นตัวเลข', 'harvests.delete': 'ลบ', 'harvests.deleteTitle': 'ลบบันทึกการเก็บเกี่ยว?', 'harvests.deleteMessage': 'การลบไม่สามารถย้อนกลับได้', 'harvests.cancel': 'ยกเลิก', 'harvests.save': 'บันทึกการเก็บเกี่ยว', 'harvests.untitled': 'เก็บเกี่ยว', 'harvests.noField': 'ไม่มีแปลง', 'harvests.noCrop': 'ไม่มีพืช', 'harvests.edit': 'แก้ไขการเก็บเกี่ยว', 'harvests.update': 'อัปเดตการเก็บเกี่ยว', 'sales.title': 'บันทึกการขาย', 'sales.loading': 'กำลังโหลดการขาย...', 'sales.empty': 'ยังไม่มีบันทึกการขาย', 'sales.saved': 'บันทึกแล้ว', 'sales.new': 'เพิ่มการขาย', 'sales.field': 'แปลง', 'sales.crop': 'พืช', 'sales.harvest': 'เก็บเกี่ยว (ไม่บังคับ)', 'sales.selectField': 'เลือกแปลง', 'sales.selectCrop': 'เลือกพืช', 'sales.selectHarvest': 'เลือกการเก็บเกี่ยว', 'sales.noHarvest': 'ยังไม่มีการเก็บเกี่ยว', 'sales.date': 'วันที่ขาย', 'sales.datePlaceholder': 'YYYY-MM-DD', 'sales.quantity': 'ปริมาณ', 'sales.quantityPlaceholder': 'เช่น 50', 'sales.unit': 'หน่วย', 'sales.unitPlaceholder': 'กก.', 'sales.price': 'ราคา', 'sales.pricePlaceholder': 'เช่น 35', 'sales.priceLabel': 'ราคา:', 'sales.buyer': 'ผู้ซื้อ', 'sales.buyerPlaceholder': 'เช่น ตลาดท้องถิ่น', 'sales.notes': 'บันทึก', 'sales.notesPlaceholder': 'การชำระเงิน ขนส่ง คุณภาพ...', 'sales.fieldRequired': 'ต้องเลือกแปลง', 'sales.cropRequired': 'ต้องเลือกพืช', 'sales.quantityInvalid': 'ปริมาณต้องเป็นตัวเลข', 'sales.delete': 'ลบ', 'sales.deleteTitle': 'ลบบันทึกการขาย?', 'sales.deleteMessage': 'การลบไม่สามารถย้อนกลับได้', 'sales.cancel': 'ยกเลิก', 'sales.save': 'บันทึกการขาย', 'sales.untitled': 'การขาย', 'sales.noField': 'ไม่มีแปลง', 'sales.noCrop': 'ไม่มีพืช', 'sales.edit': 'แก้ไขการขาย', 'sales.update': 'อัปเดตการขาย', 'costs.title': 'บันทึกต้นทุน', 'costs.loading': 'กำลังโหลดต้นทุน...', 'costs.empty': 'ยังไม่มีบันทึกต้นทุน', 'costs.saved': 'บันทึกแล้ว', 'costs.new': 'เพิ่มต้นทุน', 'costs.field': 'แปลง', 'costs.crop': 'พืช (ไม่บังคับ)', 'costs.selectField': 'เลือกแปลง', 'costs.selectCrop': 'เลือกพืช', 'costs.category': 'หมวดหมู่', 'costs.category.seed': 'เมล็ดพันธุ์', 'costs.category.fertilizer': 'ปุ๋ย', 'costs.category.labor': 'แรงงาน', 'costs.category.fuel': 'เชื้อเพลิง', 'costs.category.equipment': 'อุปกรณ์', 'costs.category.transport': 'ขนส่ง', 'costs.category.misc': 'อื่น ๆ', 'costs.categoryPlaceholder': 'เช่น เมล็ดพันธุ์', 'costs.amount': 'จำนวนเงิน', 'costs.amountPlaceholder': 'เช่น 1200', 'costs.vendor': 'ผู้ขาย', 'costs.vendorPlaceholder': 'เช่น ร้านวัสดุเกษตร', 'costs.date': 'วันที่', 'costs.datePlaceholder': 'YYYY-MM-DD', 'costs.notes': 'บันทึก', 'costs.notesPlaceholder': 'ใบเสร็จ การใช้งาน วัตถุประสงค์...', 'costs.photo': 'รูปใบเสร็จ', 'costs.pickPhoto': 'เลือกรูป', 'costs.takePhoto': 'ถ่ายรูป', 'costs.noPhoto': 'ยังไม่ได้เลือกรูป', 'costs.fieldRequired': 'ต้องเลือกแปลง', 'costs.amountInvalid': 'จำนวนเงินต้องเป็นตัวเลข', 'costs.delete': 'ลบ', 'costs.deleteTitle': 'ลบบันทึกต้นทุน?', 'costs.deleteMessage': 'การลบไม่สามารถย้อนกลับได้', 'costs.cancel': 'ยกเลิก', 'costs.save': 'บันทึกต้นทุน', 'costs.edit': 'แก้ไขต้นทุน', 'costs.update': 'อัปเดตต้นทุน', 'costs.untitled': 'ต้นทุน', 'costs.noField': 'ไม่มีแปลง', 'costs.noCrop': 'ไม่มีพืช', 'demo.field.north': 'แปลงเหนือ', 'demo.field.northNote': 'ดินร่วน · น้ำหยด', 'demo.field.river': 'แปลงริมน้ำ', 'demo.field.riverNote': 'พื้นที่ลุ่มใกล้คลอง', 'demo.field.greenhouse': 'โรงเรือน', 'demo.field.greenhouseNote': 'แปลงในร่ม รดน้ำทุกวัน', 'demo.field.orchard': 'แปลงสวนผลไม้', 'demo.field.orchardNote': 'ยกร่องและมีแนวกันลมด้านตะวันออก', 'demo.field.terrace': 'แปลงขั้นบันได', 'demo.field.terraceNote': 'พื้นที่ลาดชันแบ่งขั้น พร้อมน้ำหยด', 'demo.crop.tomato': 'มะเขือเทศ', 'demo.crop.tomatoVariety': 'เชอรี่', 'demo.crop.rice': 'ข้าว', 'demo.crop.riceVariety': 'หอมมะลิ', 'demo.crop.lettuce': 'ผักกาดหอม', 'demo.crop.lettuceVariety': 'บัตเตอร์เฮด', 'demo.crop.chili': 'พริก', 'demo.crop.chiliVariety': 'พริกขี้หนู', 'demo.crop.cabbage': 'กะหล่ำปลี', 'demo.crop.cabbageVariety': 'กะหล่ำปลีเขียว', 'demo.observation.scoutingNote': 'พบบางส่วนใบเป็นจุดเริ่มต้นตามขอบแปลง', 'demo.observation.diseaseNote': 'พบรอยโรคหลังฝนตก', 'demo.observation.irrigationNote': 'ปรับเวลารดน้ำเป็นช่วงเย็น', 'demo.observation.pestNote': 'พบเพลี้ยอ่อนตามยอดอ่อน', 'demo.observation.nutrientNote': 'ใบล่างซีด ให้ปุ๋ยทางใบเพิ่ม', 'demo.task.note': 'ทำงานเสร็จตามแผน', 'demo.task.note2': 'ทำตามเช็กลิสต์มาตรฐาน', 'demo.task.note3': 'ตรวจอุปกรณ์และบันทึกค่าแล้ว', 'demo.harvest.note1': 'เก็บช่วงเช้า คุณภาพดี', 'demo.harvest.note2': 'เก็บหลังฝนตกเล็กน้อย', 'demo.harvest.note3': 'คัดขนาดเพื่อขาย', 'demo.sale.buyer1': 'ตลาดท้องถิ่น', 'demo.sale.buyer2': 'ผู้ซื้อส่ง', 'demo.sale.buyer3': 'คู่ค้าร้านอาหาร', 'demo.sale.note1': 'ส่งของในวันเดียวกัน', 'demo.sale.note2': 'ชำระเงินครบถ้วน', 'demo.sale.note3': 'ขอสั่งประจำทุกสัปดาห์', 'demo.cost.vendor1': 'ร้านวัสดุเกษตร', 'demo.cost.vendor2': 'ร้านปุ๋ย', 'demo.cost.vendor3': 'ทีมแรงงาน', 'demo.cost.note1': 'เมล็ดมะเขือเทศและถาดเพาะ', 'demo.cost.note2': 'ปุ๋ยรองพื้นแปลงข้าว', 'demo.cost.note3': 'แรงงานช่วยเก็บเกี่ยว (ครึ่งวัน)', 'observations.type.scouting': 'สำรวจ', 'observations.type.pest': 'แมลง', 'observations.type.disease': 'โรค', 'observations.type.irrigation': 'ให้น้ำ', 'observations.type.weeds': 'วัชพืช', 'observations.type.nutrients': 'ธาตุอาหาร', 'crops.title': 'พืช', 'crops.loading': 'กำลังโหลดพืช...', 'crops.empty': 'ยังไม่มีพืช', 'crops.saved': 'บันทึกแล้ว', 'crops.field': 'แปลง', 'crops.selectField': 'เลือกแปลง', 'crops.name': 'ชื่อพืช', 'crops.variety': 'สายพันธุ์', 'crops.planting': 'วันที่ปลูก', 'crops.harvest': 'คาดว่าจะเก็บเกี่ยว', 'crops.namePlaceholder': 'เช่น มะเขือเทศ', 'crops.varietyPlaceholder': 'เช่น เชอรี่', 'crops.plantingPlaceholder': 'YYYY-MM-DD', 'crops.harvestPlaceholder': 'YYYY-MM-DD', 'crops.fieldRequired': 'ต้องเลือกแปลง', 'crops.nameRequired': 'ต้องกรอกชื่อพืช', 'crops.delete': 'ลบ', 'crops.deleteTitle': 'ลบพืชนี้ไหม?', 'crops.deleteMessage': 'การลบไม่สามารถย้อนกลับได้', 'crops.noField': 'ไม่มีแปลง', 'crops.untitled': 'พืช', 'crops.plantingLabel': 'ปลูก:', 'crops.harvestLabel': 'เก็บเกี่ยว:', 'crops.save': 'บันทึกพืช', 'crops.new': 'เพิ่มพืช', 'crops.photo': 'รูปพืช', 'crops.pickPhoto': 'เลือกรูป', 'crops.takePhoto': 'ถ่ายรูป', 'crops.noPhoto': 'ยังไม่ได้เลือกรูป', 'crops.today': 'วันนี้', 'crops.done': 'เสร็จ', 'crops.edit': 'แก้ไขพืช', 'crops.update': 'อัปเดตพืช', 'crops.cancel': 'ยกเลิก', }, }; function getDeviceLanguage(): Language { try { const locale = Intl.DateTimeFormat().resolvedOptions().locale; if (locale.toLowerCase().startsWith('th')) return 'th'; } catch { // fall through } return 'en'; } type LocalizationContextValue = { language: Language; setLanguage: (language: Language) => void; t: (key: string, params?: Params) => string; }; const LocalizationContext = createContext(null); export function LocalizationProvider({ children }: { children: ReactNode }) { const [language, setLanguage] = useState(getDeviceLanguage()); const t = useCallback( (key: string, params?: Params) => { const template = strings[language][key] ?? strings.en[key] ?? key; if (!params) return template; return Object.keys(params).reduce((result, paramKey) => { return result.replace( new RegExp(`{{${paramKey}}}`, 'g'), String(params[paramKey]) ); }, template); }, [language] ); const value = useMemo( () => ({ language, setLanguage, t }), [language, setLanguage, t] ); return {children}; } export function useTranslation() { const ctx = useContext(LocalizationContext); if (!ctx) { throw new Error('useTranslation must be used within LocalizationProvider'); } return ctx; }