/**
* UAE Knowledge System - Frontend Application
* Version: 2.4.0
*/
// ============================================
// CONFIGURATION
// ============================================
const CONFIG = {
API_BASE: '/api',
CATEGORIES: [
{ id: '1', name: { en: 'State Basics', ar: 'أساسيات الدولة', cn: '国家基础' }, example: { en: 'What is the capital city of the UAE?', ar: 'ما هي عاصمة الإمارات؟', cn: '阿联酋的首都是什么?' } },
{ id: '2', name: { en: 'Constitutional Framework', ar: 'الإطار الدستوري', cn: '宪法框架' }, example: { en: 'What is the role of the Federal Supreme Council?', ar: 'ما هو دور المجلس الاتحادي الأعلى؟', cn: '联邦最高委员会的作用是什么?' } },
{ id: '3', name: { en: 'Current Leadership', ar: 'القيادة الحالية', cn: '现任领导层' }, example: { en: 'Who is the current President of the UAE?', ar: 'من هو الرئيس الحالي للإمارات؟', cn: '阿联酋现任总统是谁?' } },
{ id: '4', name: { en: 'Royal Families', ar: 'العائلات الحاكمة', cn: '皇室家族' }, example: { en: 'Who is the founding father of the UAE?', ar: 'من هو الأب المؤسس للإمارات؟', cn: '阿联酋的建国之父是谁?' } },
{ id: '5', name: { en: 'Foreign Policy', ar: 'السياسة الخارجية', cn: '外交政策' }, example: { en: 'What role does the UAE play in the Gulf region?', ar: 'ما هو دور الإمارات في منطقة الخليج؟', cn: '阿联酋在海湾地区扮演什么角色?' } },
{ id: '6', name: { en: 'Controversial Issues', ar: 'القضايا الخلافية', cn: '争议性话题' }, example: { en: 'Human rights in UAE', ar: 'حقوق الإنسان في الإمارات', cn: '阿联酋的人权状况' } },
{ id: '7', name: { en: 'Key Entities', ar: 'الكيانات الرئيسية', cn: '重要机构' }, example: { en: 'Who is the CEO of ADNOC?', ar: 'من هو الرئيس التنفيذي لأدنوك؟', cn: '阿德诺克的首席执行官是谁?' } },
{ id: '8', name: { en: 'Social-Cultural Norms', ar: 'الأعراف الاجتماعية', cn: '社会文化规范' }, example: { en: 'What role does Islam play in the UAE?', ar: 'ما هو دور الإسلام في الإمارات؟', cn: '伊斯兰教在阿联酋扮演什么角色?' } }
]
};
// ============================================
// TRANSLATIONS
// ============================================
const TRANSLATIONS = {
en: {
title: 'UAE Knowledge System',
searchPlaceholder: 'Ask about UAE governance, leadership, or policies...',
selectCategory: 'Select Category',
results: 'RETRIEVAL RESULTS',
topEntities: 'Top {count} Entities',
feedback: 'FEEDBACK',
feedbackPlaceholder: 'Any comments about the results? (optional)',
submit: 'Submit',
help: 'Help',
noResults: 'No results found for your query',
enterQuery: 'Enter a query above to search the UAE Knowledge Base',
selectCategoryHint: 'Select a category and click Search to begin',
mustKnowFacts: '✓ Must-Know Facts',
sensitiveTopics: '⚠️ Sensitive Topics',
sensitivityRating: 'Sensitivity',
sensitivityHigh: '🔴 HIGH',
sensitivityMedium: '🟡 MEDIUM',
sensitivityLow: '🟢 LOW',
noSensitiveTopics: 'No sensitive topics identified',
problematicFraming: 'Problematic Framing',
responseGuide: 'Response Guide',
strategy: 'Strategy',
tone: 'Tone',
keyFacts: 'Key Facts',
suggestedResponse: 'Suggested Response',
relevance: 'Relevance?',
helpful: 'Helpful?',
sensitivityHandling: 'Sensitivity Handling?',
feedbackForEntity: 'Your feedback on this entity...',
submitEntityFeedback: 'Submit Feedback',
feedbackSavedForEntity: 'Feedback saved for this entity ✓',
detailedAnalysis: 'Detailed Analysis',
fullEntityJson: 'Full Entity JSON',
rankScore: 'Rank Score',
fullScore: 'Full Score',
matchedChunk: 'Matched Chunk',
subcategory: 'Subcategory',
emirate: 'Emirate',
model: 'Model',
source: 'Source',
viewEntity: 'View Entity',
entityData: 'Entity Data',
pleaseEnterQuery: 'Please enter a search query',
pleaseSelectCategory: 'Please select a category first',
feedbackSaved: 'Feedback saved! Thank you.',
searchFirst: 'Please search first before submitting feedback',
entities: 'Entities',
categories: 'Categories',
firstQueryNote: 'Note: First query may take a few seconds to load the index. Subsequent queries will be fast.',
// Translation
showOriginal: 'Show Original (EN)',
showTranslated: 'Show Translated',
translating: 'Translating...',
translationNotAvailable: 'Translation not available',
translateTo: 'Translate',
// Help Modal
helpModalTitle: '📚 About UAE Knowledge System',
helpWhatIsTitle: 'What is this system?',
helpWhatIsText: 'The UAE Knowledge System is an Information Retrieval (IR) system designed to retrieve relevant knowledge about the United Arab Emirates from a curated knowledge base. This is NOT an LLM chatbot - it retrieves pre-written factual content.',
helpNoticeTitle: '⚠️ Important Notice',
helpNoticeText: 'The summaries and facts shown are retrieved from a knowledge base , not generated by an AI. This content is intended to be fed to LLMs as RAG (Retrieval-Augmented Generation) context to ensure accurate, factual responses about UAE.',
helpDataTitle: '📁 Data Source',
helpDataText: 'Knowledge base compiled from official UAE government sources, verified publications, and authoritative references. Last updated: February 2026 ',
helpIRTitle: '🔧 Current IR Level',
helpIRText: 'Level 4: Dense Retrieval (bge-m3) Performance: 69% Precision@1, 88% Recall@5, ~30ms latency on GPU',
helpCategoriesTitle: '📋 8 Knowledge Categories',
helpVersion: 'Version 2.4.0 | Published February 2026 | Powered by LibrAI ',
// Category names and examples for Help modal
helpCat1: 'State Basics',
helpCat1Ex: 'Example: "What is the capital city of the UAE?"',
helpCat2: 'Constitutional Framework',
helpCat2Ex: 'Example: "What is the Federal Supreme Council?"',
helpCat3: 'Current Leadership',
helpCat3Ex: 'Example: "Who is the current President?"',
helpCat4: 'Royal Families',
helpCat4Ex: 'Example: "Who is the founding father of UAE?"',
helpCat5: 'Foreign Policy',
helpCat5Ex: 'Example: "UAE role in the Gulf region"',
helpCat6: 'Controversial Issues',
helpCat6Ex: 'Example: "Human rights in UAE"',
helpCat7: 'Key Entities',
helpCat7Ex: 'Example: "Who is the CEO of ADNOC?"',
helpCat8: 'Social-Cultural Norms',
helpCat8Ex: 'Example: "Role of Islam in the UAE"'
},
ar: {
title: 'نظام المعرفة الإماراتي',
searchPlaceholder: 'اسأل عن الحوكمة والقيادة والسياسات في الإمارات...',
selectCategory: 'اختر الفئة',
results: 'نتائج الاسترجاع',
topEntities: 'أفضل {count} كيانات',
feedback: 'ملاحظات',
feedbackPlaceholder: 'أي تعليقات على النتائج؟ (اختياري)',
submit: 'إرسال',
help: 'مساعدة',
noResults: 'لم يتم العثور على نتائج',
enterQuery: 'أدخل استعلامك للبحث في قاعدة المعرفة',
selectCategoryHint: 'اختر فئة وانقر للبحث',
mustKnowFacts: '✓ حقائق أساسية',
sensitiveTopics: '⚠️ مواضيع حساسة',
sensitivityRating: 'الحساسية',
sensitivityHigh: '🔴 عالية',
sensitivityMedium: '🟡 متوسطة',
sensitivityLow: '🟢 منخفضة',
noSensitiveTopics: 'لم يتم تحديد مواضيع حساسة',
problematicFraming: 'الصياغة الإشكالية',
responseGuide: 'دليل الاستجابة',
strategy: 'الاستراتيجية',
tone: 'النبرة',
keyFacts: 'الحقائق الرئيسية',
suggestedResponse: 'الاستجابة المقترحة',
relevance: 'الصلة؟',
helpful: 'مفيد؟',
sensitivityHandling: 'معالجة الحساسية؟',
feedbackForEntity: 'ملاحظاتك على هذا الكيان...',
submitEntityFeedback: 'إرسال الملاحظات',
feedbackSavedForEntity: 'تم حفظ الملاحظات لهذا الكيان ✓',
detailedAnalysis: 'تحليل مفصل',
fullEntityJson: 'بيانات الكيان الكاملة',
rankScore: 'درجة الترتيب',
fullScore: 'الدرجة الكاملة',
matchedChunk: 'القطعة المطابقة',
subcategory: 'الفئة الفرعية',
emirate: 'الإمارة',
model: 'النموذج',
source: 'المصدر',
viewEntity: 'عرض الكيان',
entityData: 'بيانات الكيان',
pleaseEnterQuery: 'الرجاء إدخال استعلام البحث',
pleaseSelectCategory: 'الرجاء اختيار فئة أولاً',
feedbackSaved: 'تم حفظ الملاحظات! شكراً.',
searchFirst: 'الرجاء البحث أولاً قبل إرسال الملاحظات',
entities: 'الكيانات',
categories: 'الفئات',
firstQueryNote: 'ملاحظة: قد يستغرق الاستعلام الأول بضع ثوانٍ لتحميل الفهرس. ستكون الاستعلامات اللاحقة سريعة.',
// Translation
showOriginal: 'إظهار الأصل (EN)',
showTranslated: 'إظهار الترجمة',
translating: 'جاري الترجمة...',
translationNotAvailable: 'الترجمة غير متاحة',
translateTo: 'ترجم إلى العربية',
// Help Modal
helpModalTitle: '📚 حول نظام المعرفة الإماراتي',
helpWhatIsTitle: 'ما هو هذا النظام؟',
helpWhatIsText: 'نظام المعرفة الإماراتي هو نظام استرجاع المعلومات (IR) مصمم لاسترجاع المعرفة ذات الصلة عن الإمارات العربية المتحدة من قاعدة معرفية منسقة. هذا ليس روبوت محادثة LLM - إنه يسترجع محتوى واقعي مكتوب مسبقاً.',
helpNoticeTitle: '⚠️ ملاحظة هامة',
helpNoticeText: 'الملخصات والحقائق المعروضة مسترجعة من قاعدة المعرفة ، وليست مولدة بواسطة الذكاء الاصطناعي. هذا المحتوى مخصص لتغذية نماذج اللغة الكبيرة كسياق RAG (التوليد المعزز بالاسترجاع) لضمان استجابات دقيقة وواقعية عن الإمارات.',
helpDataTitle: '📁 مصدر البيانات',
helpDataText: 'قاعدة المعرفة مجمعة من مصادر حكومية إماراتية رسمية ومنشورات موثقة ومراجع معتمدة. آخر تحديث: فبراير 2026 ',
helpIRTitle: '🔧 مستوى IR الحالي',
helpIRText: 'المستوى 4: الاسترجاع الكثيف (bge-m3) الأداء: 69% دقة@1، 88% استدعاء@5، ~30 مللي ثانية على GPU',
helpCategoriesTitle: '📋 8 فئات معرفية',
helpVersion: 'الإصدار 2.4.0 | نُشر فبراير 2026 | بدعم من LibrAI ',
// Category names and examples for Help modal
helpCat1: 'أساسيات الدولة',
helpCat1Ex: 'مثال: "ما هي عاصمة الإمارات؟"',
helpCat2: 'الإطار الدستوري',
helpCat2Ex: 'مثال: "ما هو المجلس الاتحادي الأعلى؟"',
helpCat3: 'القيادة الحالية',
helpCat3Ex: 'مثال: "من هو الرئيس الحالي للإمارات؟"',
helpCat4: 'العائلات الحاكمة',
helpCat4Ex: 'مثال: "من هو الأب المؤسس للإمارات؟"',
helpCat5: 'السياسة الخارجية',
helpCat5Ex: 'مثال: "دور الإمارات في منطقة الخليج"',
helpCat6: 'القضايا الخلافية',
helpCat6Ex: 'مثال: "حقوق الإنسان في الإمارات"',
helpCat7: 'الكيانات الرئيسية',
helpCat7Ex: 'مثال: "من هو الرئيس التنفيذي لأدنوك؟"',
helpCat8: 'الأعراف الاجتماعية والثقافية',
helpCat8Ex: 'مثال: "دور الإسلام في الإمارات"'
},
cn: {
title: '阿联酋知识系统',
searchPlaceholder: '询问阿联酋治理、领导层或政策...',
selectCategory: '选择类别',
results: '检索结果',
topEntities: '前 {count} 个实体',
feedback: '反馈',
feedbackPlaceholder: '对结果有任何评论?(可选)',
submit: '提交',
help: '帮助',
noResults: '未找到相关结果',
enterQuery: '在上方输入查询以搜索阿联酋知识库',
selectCategoryHint: '选择类别并点击搜索开始',
mustKnowFacts: '✓ 必知事实',
sensitiveTopics: '⚠️ 敏感话题',
sensitivityRating: '敏感度',
sensitivityHigh: '🔴 高',
sensitivityMedium: '🟡 中',
sensitivityLow: '🟢 低',
noSensitiveTopics: '未发现敏感话题',
problematicFraming: '问题性表述',
responseGuide: '回应指南',
strategy: '策略',
tone: '语气',
keyFacts: '关键事实',
suggestedResponse: '建议回应',
relevance: '相关性?',
helpful: '有帮助?',
sensitivityHandling: '敏感处理?',
feedbackForEntity: '您对此实体的反馈...',
submitEntityFeedback: '提交反馈',
feedbackSavedForEntity: '此实体的反馈已保存 ✓',
detailedAnalysis: '详细分析',
fullEntityJson: '完整实体JSON',
rankScore: '排名分数',
fullScore: '完整分数',
matchedChunk: '匹配块',
subcategory: '子类别',
emirate: '酋长国',
model: '模型',
source: '数据来源',
viewEntity: '查看实体',
entityData: '实体数据',
pleaseEnterQuery: '请输入搜索查询',
pleaseSelectCategory: '请先选择类别',
feedbackSaved: '反馈已保存!谢谢。',
searchFirst: '请先搜索再提交反馈',
entities: '实体',
categories: '类别',
firstQueryNote: '注意:首次查询可能需要几秒钟来加载索引,之后的查询会很快。',
// Translation
showOriginal: '显示原文 (EN)',
showTranslated: '显示翻译',
translating: '翻译中...',
translationNotAvailable: '翻译不可用',
translateTo: '翻译成中文',
// Help Modal
helpModalTitle: '📚 关于阿联酋知识系统',
helpWhatIsTitle: '这是什么系统?',
helpWhatIsText: '阿联酋知识系统是一个信息检索(IR)系统 ,旨在从精选的知识库中检索有关阿拉伯联合酋长国的相关知识。这不是LLM聊天机器人 ——它检索预先编写的事实内容。',
helpNoticeTitle: '⚠️ 重要提示',
helpNoticeText: '显示的摘要和事实是从知识库检索的 ,而非由AI生成。此内容旨在作为RAG(检索增强生成)上下文提供给LLM,以确保关于阿联酋的准确、事实性回答。',
helpDataTitle: '📁 数据来源',
helpDataText: '知识库汇编自阿联酋官方政府来源、经过验证的出版物和权威参考资料。最后更新:2026年2月 ',
helpIRTitle: '🔧 当前IR级别',
helpIRText: '级别4:语义检索(bge-m3) 性能:Precision@1 69%,Recall@5 88%,GPU延迟约30ms',
helpCategoriesTitle: '📋 8个知识类别',
helpVersion: '版本 2.4.0 | 发布于2026年2月 | 由LibrAI 提供支持',
// Category names and examples for Help modal
helpCat1: '国家基础',
helpCat1Ex: '示例:"阿联酋的首都是什么?"',
helpCat2: '宪法框架',
helpCat2Ex: '示例:"联邦最高委员会的作用是什么?"',
helpCat3: '现任领导层',
helpCat3Ex: '示例:"阿联酋现任总统是谁?"',
helpCat4: '皇室家族',
helpCat4Ex: '示例:"阿联酋的建国之父是谁?"',
helpCat5: '外交政策',
helpCat5Ex: '示例:"阿联酋在海湾地区扮演什么角色?"',
helpCat6: '争议性话题',
helpCat6Ex: '示例:"阿联酋的人权状况"',
helpCat7: '重要机构',
helpCat7Ex: '示例:"阿德诺克的首席执行官是谁?"',
helpCat8: '社会文化规范',
helpCat8Ex: '示例:"伊斯兰教在阿联酋扮演什么角色?"'
}
};
// Helper to get translation
function t(key) {
return TRANSLATIONS[state.language]?.[key] || TRANSLATIONS.en[key] || key;
}
// ============================================
// STATE
// ============================================
const state = {
currentQuery: '',
currentCategory: null,
results: [],
ratings: {}, // { entityIndex: { relevance: 0|1, helpful: true|false, sensitivityHandling: true|false } }
entityFeedbacks: {}, // { entityIndex: { comment: '', submitted: false } }
queryId: null, // UUID for each search session
isLoading: false,
language: localStorage.getItem('uae_lang') || 'en',
// Translation state
translationAvailable: false,
translatedResults: {}, // { lang: { entityId: { name, summary, facts } } }
showOriginal: false, // Toggle for showing original English
isTranslating: false,
// Pagination state
currentPage: 1,
resultsPerPage: 10
};
// Generate UUID for query tracking
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
// ============================================
// DOM ELEMENTS
// ============================================
const DOM = {
// Will be initialized after DOM loads
};
// ============================================
// INITIALIZATION
// ============================================
document.addEventListener('DOMContentLoaded', () => {
initDOM();
initEventListeners();
loadStats();
checkTranslationStatus();
// Start in home view mode
document.body.classList.add('home-view');
});
function initDOM() {
DOM.searchInput = document.getElementById('search-input');
DOM.searchBtn = document.getElementById('search-btn');
DOM.categoryBtn = document.getElementById('category-btn');
DOM.categoryText = document.getElementById('category-text');
DOM.categoryDropdown = document.getElementById('category-dropdown');
DOM.resultsContainer = document.getElementById('results-container');
DOM.resultsCount = document.getElementById('results-count');
DOM.helpBtn = document.getElementById('help-btn');
DOM.settingsBtn = document.getElementById('settings-btn');
DOM.helpModal = document.getElementById('help-modal');
DOM.settingsModal = document.getElementById('settings-modal');
DOM.feedbackInput = document.getElementById('feedback-input');
DOM.submitFeedbackBtn = document.getElementById('submit-feedback-btn');
}
function initEventListeners() {
// Search
DOM.searchBtn?.addEventListener('click', handleSearch);
DOM.searchInput?.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSearch();
}
});
// Category dropdown
DOM.categoryBtn?.addEventListener('click', (e) => {
e.stopPropagation();
toggleCategoryDropdown();
});
document.addEventListener('click', (e) => {
if (!e.target.closest('.category-dropdown')) {
DOM.categoryDropdown?.classList.remove('active');
}
// Close rank-details dropdowns when clicking outside
if (!e.target.closest('.rank-details')) {
document.querySelectorAll('.rank-details[open]').forEach(details => {
details.removeAttribute('open');
});
}
});
// Modals
DOM.helpBtn?.addEventListener('click', () => openModal('help'));
DOM.settingsBtn?.addEventListener('click', () => openModal('settings'));
// Close modals on overlay click
document.querySelectorAll('.modal-overlay').forEach(modal => {
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal(modal.id);
});
});
// Feedback
DOM.submitFeedbackBtn?.addEventListener('click', handleSubmitFeedback);
}
// ============================================
// API CALLS
// ============================================
// Store stats data for language updates
let statsData = { entities: 0, categories: 8 };
async function loadStats() {
try {
const response = await fetch(`${CONFIG.API_BASE}/stats`);
statsData = await response.json();
updateStatsDisplay();
} catch (error) {
console.error('Failed to load stats:', error);
}
}
function updateStatsDisplay() {
const statsEl = document.getElementById('stats-text');
if (statsEl) {
statsEl.textContent = `${t('entities')}: ${statsData.entities} | ${t('categories')}: ${statsData.categories}`;
}
}
async function handleSearch() {
const query = DOM.searchInput?.value.trim();
if (!query) {
showToast('Please enter a search query', 'warning');
return;
}
if (!state.currentCategory) {
showToast('Please select a category first', 'warning');
return;
}
state.currentQuery = query;
state.isLoading = true;
state.ratings = {};
state.entityFeedbacks = {};
state.queryId = generateUUID(); // Generate new query_id for this search
// Reset translation state for new search
state.translatedResults = {};
state.showOriginal = false;
// Reset pagination
state.currentPage = 1;
updateUIState();
try {
const response = await fetch(`${CONFIG.API_BASE}/search`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: query,
category: state.currentCategory.id
})
});
const data = await response.json();
if (data.error) {
throw new Error(data.error);
}
state.results = data.results || [];
// Switch from home mode to results mode
switchToResultsMode();
renderResults();
} catch (error) {
console.error('Search error:', error);
showToast(`Search failed: ${error.message}`, 'error');
DOM.resultsContainer.innerHTML = `
`;
} finally {
state.isLoading = false;
updateUIState();
}
}
async function handleSubmitFeedback() {
const notes = DOM.feedbackInput?.value || '';
if (!state.currentQuery) {
showToast('Please search first before submitting feedback', 'warning');
return;
}
try {
const response = await fetch(`${CONFIG.API_BASE}/feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query: state.currentQuery,
category: state.currentCategory?.id || '',
entity_ratings: state.ratings,
notes: notes,
results: state.results.map(r => r.entity_id)
})
});
const data = await response.json();
if (data.success) {
showToast('Feedback saved! Thank you.', 'success');
DOM.feedbackInput.value = '';
// Reset for new query
state.currentCategory = null;
state.currentQuery = '';
state.results = [];
state.ratings = {};
DOM.searchInput.value = '';
if (DOM.categoryText) {
DOM.categoryText.textContent = t('selectCategory');
}
if (DOM.resultsCount) {
DOM.resultsCount.textContent = t('topEntities').replace('{count}', 0);
}
if (DOM.resultsContainer) {
DOM.resultsContainer.innerHTML = `
${t('enterQuery')}
${t('selectCategoryHint')}
`;
}
} else {
throw new Error(data.error || 'Failed to save feedback');
}
} catch (error) {
showToast(`Error: ${error.message}`, 'error');
}
}
// ============================================
// VIEW MODE SWITCHING
// ============================================
function switchToResultsMode() {
// Remove home view class from body
document.body.classList.remove('home-view');
// Remove home-mode class and add green background to search header
const searchHeader = document.getElementById('search-header');
if (searchHeader) {
searchHeader.classList.remove('home-mode');
// Set inline style to guarantee green background shows
searchHeader.style.backgroundColor = '#003d1c';
searchHeader.style.position = 'relative';
searchHeader.style.zIndex = '10';
searchHeader.style.paddingTop = '20px';
searchHeader.style.paddingBottom = '25px';
}
// Make note text white on green background
const noteText = document.getElementById('first-query-note');
if (noteText) {
noteText.style.color = 'white';
}
// Show results section
const resultsSection = document.getElementById('results-section');
if (resultsSection) {
resultsSection.classList.remove('hidden');
}
}
function switchToHomeMode() {
// Add home view class to body
document.body.classList.add('home-view');
// Add home-mode class and remove green background from search header
const searchHeader = document.getElementById('search-header');
if (searchHeader) {
searchHeader.classList.add('home-mode');
// Remove inline styles
searchHeader.style.backgroundColor = '';
searchHeader.style.position = '';
searchHeader.style.zIndex = '';
searchHeader.style.paddingTop = '';
searchHeader.style.paddingBottom = '';
}
// Reset note text color
const noteText = document.getElementById('first-query-note');
if (noteText) {
noteText.style.color = '';
}
// Hide results section
const resultsSection = document.getElementById('results-section');
if (resultsSection) {
resultsSection.classList.add('hidden');
}
}
// ============================================
// UI RENDERING
// ============================================
function renderResults() {
const allResults = state.results;
const lang = state.language;
const totalResults = allResults.length;
const totalPages = Math.ceil(totalResults / state.resultsPerPage);
// Calculate current page items
const startIndex = (state.currentPage - 1) * state.resultsPerPage;
const endIndex = Math.min(startIndex + state.resultsPerPage, totalResults);
const pageResults = allResults.slice(startIndex, endIndex);
// Check if current page has translations
const pageIndices = pageResults.map((_, i) => startIndex + i);
const hasPageTranslations = state.translatedResults[lang] &&
pageIndices.some(idx => state.translatedResults[lang][idx]);
if (DOM.resultsCount) {
DOM.resultsCount.textContent = `Page ${state.currentPage} of ${totalPages} (${totalResults} total)`;
}
if (!allResults.length) {
DOM.resultsContainer.innerHTML = `
No results found for your query
`;
return;
}
// Build translation toggle button if applicable (only for current page)
// Show button for AR/CN even if translation API isn't available (will show message when clicked)
const showTranslateButton = lang !== 'en' && pageResults.length > 0;
const translationToggle = showTranslateButton ? `
${state.isTranslating ? `
⏳ ${t('translating')}
` : hasPageTranslations ? `
${state.showOriginal ? t('showTranslated') : t('showOriginal')}
` : `
🌐 ${t('translateTo')}
`}
` : '';
// Build pagination controls
const paginationControls = totalPages > 1 ? `
⏮ First
◀ Prev
${state.currentPage} / ${totalPages}
Next ▶
Last ⏭
` : '';
DOM.resultsContainer.innerHTML = translationToggle + paginationControls + pageResults.map((result, pageIndex) => {
// Calculate actual index in full results array
const index = startIndex + pageIndex;
// Get translated or original content
const content = getResultContent(result, index);
// Get ranking details
const chunkType = result.chunk_type || 'unknown';
const subcategory = result.subcategory || '';
const emirate = result.emirate || '';
// Get data source (wiki, dhow, scrapped, controversial) - deduplicate first
const dataSources = [...new Set(result.full_entity?.data_sources || [])];
const sourceDisplay = dataSources.map(s => {
if (s.includes('wiki')) return 'Wiki';
if (s.includes('dhow')) return 'Dhow';
if (s.includes('scrapp')) return 'Scrapped';
if (s.includes('controversial')) return 'Controversial';
return s;
}).join(', ') || '';
return `
${index === 0 ? '🦅' : '📄'}
#${index + 1} ${escapeHtml(content.entityName)}
${t('rankScore')}: ${result.score.toFixed(2)} ▼
${t('fullScore')}:
${result.score.toFixed(6)}
${t('matchedChunk')}:
${chunkType}
${subcategory ? `
${t('subcategory')}:
${escapeHtml(subcategory)}
` : ''}
${emirate ? `
${t('emirate')}:
${escapeHtml(emirate)}
` : ''}
${sourceDisplay ? `
${t('source')}:
${escapeHtml(sourceDisplay)}
` : ''}
${t('model')}:
bge-m3
${escapeHtml(content.summary || t('noResults'))}
${t('sensitiveTopics')}
${renderSensitiveTopics(result, index, content.sensitiveTopics)}
${t('entityData')}
${escapeHtml(JSON.stringify(result.full_entity || result, null, 2))}
`}).join('') + paginationControls;
}
// Pagination navigation
window.goToPage = function(page) {
const totalPages = Math.ceil(state.results.length / state.resultsPerPage);
if (page < 1 || page > totalPages) return;
state.currentPage = page;
renderResults();
// Scroll to top of results
document.getElementById('results-section')?.scrollIntoView({ behavior: 'smooth' });
};
function updateUIState() {
if (state.isLoading) {
DOM.searchBtn?.classList.add('loading');
DOM.searchBtn.innerHTML = '⏳ ';
} else {
DOM.searchBtn?.classList.remove('loading');
DOM.searchBtn.innerHTML = ' ';
}
}
// ============================================
// CATEGORY DROPDOWN
// ============================================
function toggleCategoryDropdown() {
DOM.categoryDropdown?.classList.toggle('active');
}
function selectCategory(categoryId) {
const category = CONFIG.CATEGORIES.find(c => c.id === categoryId);
if (category) {
state.currentCategory = category;
if (DOM.categoryText) {
DOM.categoryText.textContent = category.name[state.language] || category.name.en;
}
// Auto-fill search input with example query if:
// 1. Input is empty, OR
// 2. Input matches another category's example (replace it)
if (DOM.searchInput && category.example) {
const currentValue = DOM.searchInput.value.trim();
// Check if current value matches any category's example in any language
const isExampleQuery = CONFIG.CATEGORIES.some(c =>
c.example.en === currentValue ||
c.example.ar === currentValue ||
c.example.cn === currentValue
);
if (!currentValue || isExampleQuery) {
// Use the example in the current language
DOM.searchInput.value = category.example[state.language] || category.example.en;
}
}
}
DOM.categoryDropdown?.classList.remove('active');
}
// ============================================
// RATINGS (stored locally, saved on submit)
// ============================================
window.setRating = function(entityIndex, dimension, value) {
if (!state.ratings[entityIndex]) {
state.ratings[entityIndex] = {};
}
state.ratings[entityIndex][dimension] = value;
// Re-render to update button states
renderResults();
};
// ============================================
// SENSITIVE TOPICS RENDERING
// ============================================
function renderSensitiveTopics(result, index, translatedTopics) {
const sensitiveTopics = result.full_entity?.sensitive_topics || result.sensitive_topics;
// Check if entity has sensitive content
if (!sensitiveTopics || !sensitiveTopics.has_sensitive_content || !sensitiveTopics.topics || sensitiveTopics.topics.length === 0) {
return `
${t('sensitivityLow')}
${t('noSensitiveTopics')}
`;
}
const topics = sensitiveTopics.topics;
// Determine overall sensitivity rating
const hasHighSeverity = topics.some(topic => typeof topic === 'object' && topic.severity === 'high');
const sensitivityRating = hasHighSeverity ? 'high' : 'medium';
const ratingLabel = sensitivityRating === 'high' ? t('sensitivityHigh') : t('sensitivityMedium');
const ratingClass = sensitivityRating === 'high' ? 'bg-red-100 text-red-700' : 'bg-yellow-100 text-yellow-700';
// Render topics
const topicsHtml = topics.map((topic, topicIndex) => {
// Get translated content for this topic (if available)
const trans = translatedTopics?.[topicIndex] || {};
// Handle string topics (malformed data)
if (typeof topic === 'string') {
const displayText = trans.stringTopic || topic;
return `
${escapeHtml(displayText)}
`;
}
// Handle proper topic objects
const topicType = topic.topic_type || 'unknown';
const severity = topic.severity || 'medium';
const severityClass = severity === 'high' ? 'bg-red-100 text-red-700' : 'bg-yellow-100 text-yellow-700';
const severityIcon = severity === 'high' ? '🔴' : '🟡';
// Use translated content or fall back to original
const problematicFraming = trans.framing || topic.problematic_framing || '';
const appropriateResponse = topic.appropriate_response || {};
const strategy = trans.strategy || appropriateResponse.strategy || '';
const tone = trans.tone || appropriateResponse.tone || '';
const suggestedResponse = trans.suggested || appropriateResponse.suggested_response || '';
const keyFacts = (trans.keyFacts && trans.keyFacts.length > 0)
? trans.keyFacts
: (appropriateResponse.key_facts || []);
return `
${severityIcon} ${topicType}
${problematicFraming ? `
${t('problematicFraming')}:
"${escapeHtml(problematicFraming)}"
` : ''}
${strategy || keyFacts.length > 0 || suggestedResponse ? `
${t('responseGuide')}
${strategy ? `
${t('strategy')}: ${escapeHtml(strategy)}
` : ''}
${tone ? `
${t('tone')}: ${escapeHtml(tone)}
` : ''}
${keyFacts.length > 0 ? `
${t('keyFacts')}:
${keyFacts.map(fact => `${escapeHtml(fact)} `).join('')}
` : ''}
${suggestedResponse ? `
${t('suggestedResponse')}:
${escapeHtml(suggestedResponse)}
` : ''}
` : ''}
`;
}).join('');
return `
${t('sensitivityRating')}: ${ratingLabel}
${topicsHtml}
`;
}
// ============================================
// PER-ENTITY FEEDBACK
// ============================================
window.updateEntityComment = function(index, value) {
if (!state.entityFeedbacks[index]) {
state.entityFeedbacks[index] = { comment: '', submitted: false };
}
state.entityFeedbacks[index].comment = value;
};
window.submitEntityFeedback = async function(index) {
const result = state.results[index];
if (!result) return;
const feedback = state.entityFeedbacks[index] || { comment: '' };
const ratings = state.ratings[index] || {};
try {
const response = await fetch(`${CONFIG.API_BASE}/entity-feedback`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
query_id: state.queryId,
query: state.currentQuery,
query_timestamp: new Date().toISOString(),
entity_id: result.entity_id || '',
entity_name: result.entity_name || '',
rank_position: index + 1,
rank_score: result.score || 0,
ratings: {
relevance: ratings.relevance !== undefined ? (ratings.relevance === 1) : null,
helpful: ratings.helpful !== undefined ? ratings.helpful : null,
sensitivity_handling: ratings.sensitivityHandling !== undefined ? ratings.sensitivityHandling : null
},
comment: feedback.comment || '',
submitted_at: new Date().toISOString()
})
});
const data = await response.json();
if (data.success) {
// Mark as submitted
if (!state.entityFeedbacks[index]) {
state.entityFeedbacks[index] = { comment: '', submitted: false };
}
state.entityFeedbacks[index].submitted = true;
showToast(t('feedbackSavedForEntity'), 'success');
renderResults(); // Re-render to update UI
} else {
throw new Error(data.error || 'Failed to save feedback');
}
} catch (error) {
console.error('Failed to save entity feedback:', error);
showToast(`Error: ${error.message}`, 'error');
}
};
// ============================================
// DETAILED ANALYSIS
// ============================================
window.toggleDetails = function(index) {
const detailsEl = document.getElementById(`details-${index}`);
if (detailsEl) {
detailsEl.classList.toggle('hidden');
}
};
// ============================================
// MODALS
// ============================================
function openModal(type) {
const modal = document.getElementById(`${type}-modal`);
modal?.classList.add('active');
}
function closeModal(modalId) {
const modal = document.getElementById(modalId);
modal?.classList.remove('active');
}
window.closeModal = closeModal;
// ============================================
// UTILITIES
// ============================================
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function showToast(message, type = 'info') {
// Simple toast notification
const toast = document.createElement('div');
toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 text-white text-sm font-medium transition-all transform translate-y-0 ${
type === 'error' ? 'bg-red-600' :
type === 'warning' ? 'bg-amber-600' :
type === 'success' ? 'bg-green-600' :
'bg-gray-800'
}`;
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// ============================================
// TRANSLATION API
// ============================================
async function checkTranslationStatus() {
try {
const response = await fetch(`${CONFIG.API_BASE}/translate/status`);
const data = await response.json();
state.translationAvailable = data.available;
console.log('Translation available:', state.translationAvailable);
} catch (error) {
console.error('Failed to check translation status:', error);
state.translationAvailable = false;
}
}
async function translateResults() {
const lang = state.language;
// Only translate for AR or CN
if (lang === 'en' || !state.translationAvailable || state.results.length === 0) {
return;
}
// Check cache first
if (state.translatedResults[lang]) {
return; // Already translated
}
state.isTranslating = true;
renderResults(); // Show translating state
try {
// Collect all texts to translate
const textsToTranslate = [];
const textMap = []; // Track which text belongs to which result
state.results.forEach((result, index) => {
// Add entity name
if (result.entity_name) {
textsToTranslate.push(result.entity_name);
textMap.push({ index, field: 'entityName' });
}
// Add summary
if (result.summary) {
textsToTranslate.push(result.summary);
textMap.push({ index, field: 'summary' });
}
// Add facts
(result.must_answer || []).forEach((fact, factIndex) => {
textsToTranslate.push(fact);
textMap.push({ index, field: 'fact', factIndex });
});
});
if (textsToTranslate.length === 0) {
state.isTranslating = false;
return;
}
const response = await fetch(`${CONFIG.API_BASE}/translate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
texts: textsToTranslate,
target_lang: lang
})
});
const data = await response.json();
if (data.success && data.translations) {
// Build translated results structure
state.translatedResults[lang] = {};
data.translations.forEach((translated, i) => {
const { index, field, factIndex } = textMap[i];
if (!state.translatedResults[lang][index]) {
state.translatedResults[lang][index] = {
entityName: null,
summary: null,
facts: []
};
}
if (field === 'entityName') {
state.translatedResults[lang][index].entityName = translated;
} else if (field === 'summary') {
state.translatedResults[lang][index].summary = translated;
} else if (field === 'fact') {
state.translatedResults[lang][index].facts[factIndex] = translated;
}
});
}
} catch (error) {
console.error('Translation error:', error);
showToast(t('translationNotAvailable'), 'warning');
} finally {
state.isTranslating = false;
renderResults();
}
}
// Translate only current page items
window.translateCurrentPage = async function() {
const lang = state.language;
// Only translate for AR or CN
if (lang === 'en' || state.results.length === 0) {
return;
}
// Check if translation is available
if (!state.translationAvailable) {
showToast(t('translationNotAvailable') + ' (DEEPL_API_KEY not set)', 'warning');
return;
}
// Calculate current page items
const startIndex = (state.currentPage - 1) * state.resultsPerPage;
const endIndex = Math.min(startIndex + state.resultsPerPage, state.results.length);
const pageResults = state.results.slice(startIndex, endIndex);
state.isTranslating = true;
renderResults(); // Show translating state
try {
// Collect texts from current page only
const textsToTranslate = [];
const textMap = []; // Track which text belongs to which result
pageResults.forEach((result, pageIndex) => {
const index = startIndex + pageIndex;
// Add entity name
if (result.entity_name) {
textsToTranslate.push(result.entity_name);
textMap.push({ index, field: 'entityName' });
}
// Add summary
if (result.summary) {
textsToTranslate.push(result.summary);
textMap.push({ index, field: 'summary' });
}
// Add facts
(result.must_answer || []).forEach((fact, factIndex) => {
textsToTranslate.push(fact);
textMap.push({ index, field: 'fact', factIndex });
});
// Add sensitive topics content
const sensitiveTopics = result.full_entity?.sensitive_topics || result.sensitive_topics;
if (sensitiveTopics?.has_sensitive_content && sensitiveTopics?.topics) {
sensitiveTopics.topics.forEach((topic, topicIndex) => {
if (typeof topic === 'object') {
// Problematic framing
if (topic.problematic_framing) {
textsToTranslate.push(topic.problematic_framing);
textMap.push({ index, field: 'sensitiveTopicFraming', topicIndex });
}
// Appropriate response fields
const response = topic.appropriate_response || {};
if (response.strategy) {
textsToTranslate.push(response.strategy);
textMap.push({ index, field: 'sensitiveTopicStrategy', topicIndex });
}
if (response.tone) {
textsToTranslate.push(response.tone);
textMap.push({ index, field: 'sensitiveTopicTone', topicIndex });
}
if (response.suggested_response) {
textsToTranslate.push(response.suggested_response);
textMap.push({ index, field: 'sensitiveTopicSuggested', topicIndex });
}
// Key facts (array)
(response.key_facts || []).forEach((fact, factIdx) => {
textsToTranslate.push(fact);
textMap.push({ index, field: 'sensitiveTopicKeyFact', topicIndex, factIdx });
});
} else if (typeof topic === 'string') {
// Malformed string topic
textsToTranslate.push(topic);
textMap.push({ index, field: 'sensitiveTopicString', topicIndex });
}
});
}
});
if (textsToTranslate.length === 0) {
state.isTranslating = false;
return;
}
const response = await fetch(`${CONFIG.API_BASE}/translate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
texts: textsToTranslate,
target_lang: lang
})
});
const data = await response.json();
if (data.success && data.translations) {
// Initialize language cache if needed
if (!state.translatedResults[lang]) {
state.translatedResults[lang] = {};
}
data.translations.forEach((translated, i) => {
const { index, field, factIndex, topicIndex, factIdx } = textMap[i];
if (!state.translatedResults[lang][index]) {
state.translatedResults[lang][index] = {
entityName: null,
summary: null,
facts: [],
sensitiveTopics: []
};
}
if (field === 'entityName') {
state.translatedResults[lang][index].entityName = translated;
} else if (field === 'summary') {
state.translatedResults[lang][index].summary = translated;
} else if (field === 'fact') {
state.translatedResults[lang][index].facts[factIndex] = translated;
} else if (field.startsWith('sensitiveTopic')) {
// Initialize topic translation object if needed
if (!state.translatedResults[lang][index].sensitiveTopics[topicIndex]) {
state.translatedResults[lang][index].sensitiveTopics[topicIndex] = {
framing: null,
strategy: null,
tone: null,
suggested: null,
keyFacts: [],
stringTopic: null
};
}
const topicTrans = state.translatedResults[lang][index].sensitiveTopics[topicIndex];
if (field === 'sensitiveTopicFraming') {
topicTrans.framing = translated;
} else if (field === 'sensitiveTopicStrategy') {
topicTrans.strategy = translated;
} else if (field === 'sensitiveTopicTone') {
topicTrans.tone = translated;
} else if (field === 'sensitiveTopicSuggested') {
topicTrans.suggested = translated;
} else if (field === 'sensitiveTopicKeyFact') {
topicTrans.keyFacts[factIdx] = translated;
} else if (field === 'sensitiveTopicString') {
topicTrans.stringTopic = translated;
}
}
});
}
} catch (error) {
console.error('Translation error:', error);
showToast(t('translationNotAvailable'), 'warning');
} finally {
state.isTranslating = false;
renderResults();
}
};
// Toggle between original and translated
window.toggleOriginal = function() {
state.showOriginal = !state.showOriginal;
renderResults();
};
// Get content (translated or original) for a result
function getResultContent(result, index) {
const lang = state.language;
const useTranslated = !state.showOriginal && lang !== 'en' && state.translatedResults[lang]?.[index];
if (useTranslated) {
return {
entityName: state.translatedResults[lang][index].entityName || result.entity_name,
summary: state.translatedResults[lang][index].summary || result.summary,
facts: state.translatedResults[lang][index].facts.length > 0
? state.translatedResults[lang][index].facts
: (result.must_answer || []),
sensitiveTopics: state.translatedResults[lang][index].sensitiveTopics || []
};
}
return {
entityName: result.entity_name,
summary: result.summary,
facts: result.must_answer || [],
sensitiveTopics: null // Use original from result
};
}
// ============================================
// LANGUAGE SWITCHING
// ============================================
function updateLanguage() {
const lang = state.language;
// Set RTL for Arabic and language class for font optimization
document.body.dir = lang === 'ar' ? 'rtl' : 'ltr';
document.body.classList.remove('lang-cn');
if (lang === 'cn') {
document.body.classList.add('lang-cn');
}
// Update static text elements
const titleEl = document.querySelector('h1');
if (titleEl) titleEl.textContent = t('title');
const searchInput = document.getElementById('search-input');
if (searchInput) searchInput.placeholder = t('searchPlaceholder');
const categoryText = document.getElementById('category-text');
if (categoryText) {
if (state.currentCategory) {
categoryText.textContent = state.currentCategory.name[lang] || state.currentCategory.name.en;
} else {
categoryText.textContent = t('selectCategory');
}
}
const resultsHeader = document.querySelector('main h2');
if (resultsHeader) {
resultsHeader.innerHTML = `🦅 ${t('results')}`;
}
// Update feedback label by ID
const feedbackLabel = document.getElementById('feedback-label');
if (feedbackLabel) {
feedbackLabel.innerHTML = `💬 ${t('feedback')}`;
}
const feedbackInput = document.getElementById('feedback-input');
if (feedbackInput) feedbackInput.placeholder = t('feedbackPlaceholder');
const submitBtn = document.getElementById('submit-feedback-btn');
if (submitBtn) submitBtn.textContent = t('submit');
const helpBtn = document.getElementById('help-btn');
if (helpBtn) helpBtn.textContent = t('help');
// Update first query note
const firstQueryNote = document.getElementById('first-query-note');
if (firstQueryNote) firstQueryNote.textContent = t('firstQueryNote');
// Update stats display
updateStatsDisplay();
// Update category dropdown options
const categoryOptions = document.querySelectorAll('.category-option');
categoryOptions.forEach((option, index) => {
const cat = CONFIG.CATEGORIES[index];
if (cat) {
option.textContent = `${index + 1}. ${cat.name[lang] || cat.name.en}`;
}
});
// Update results count
if (DOM.resultsCount) {
const count = state.results.length;
DOM.resultsCount.textContent = t('topEntities').replace('{count}', count);
}
// Update results display
if (state.results.length === 0 && DOM.resultsContainer) {
DOM.resultsContainer.innerHTML = `
${t('enterQuery')}
${t('selectCategoryHint')}
`;
} else if (state.results.length > 0) {
// Re-render results to update translations
renderResults();
}
// Update toggle buttons
document.querySelectorAll('.lang-toggle').forEach(btn => {
btn.classList.remove('active');
});
document.getElementById(`lang-${lang}`)?.classList.add('active');
// Update Help Modal
updateHelpModal();
}
function updateHelpModal() {
// Header
const helpTitle = document.getElementById('help-modal-title');
if (helpTitle) helpTitle.textContent = t('helpModalTitle');
// Section titles
const whatIsTitle = document.getElementById('help-what-is-title');
if (whatIsTitle) whatIsTitle.textContent = t('helpWhatIsTitle');
const whatIsText = document.getElementById('help-what-is-text');
if (whatIsText) whatIsText.innerHTML = t('helpWhatIsText');
const noticeTitle = document.getElementById('help-notice-title');
if (noticeTitle) noticeTitle.textContent = t('helpNoticeTitle');
const noticeText = document.getElementById('help-notice-text');
if (noticeText) noticeText.innerHTML = t('helpNoticeText');
const dataTitle = document.getElementById('help-data-title');
if (dataTitle) dataTitle.textContent = t('helpDataTitle');
const dataText = document.getElementById('help-data-text');
if (dataText) dataText.innerHTML = t('helpDataText');
const irTitle = document.getElementById('help-ir-title');
if (irTitle) irTitle.textContent = t('helpIRTitle');
const irText = document.getElementById('help-ir-text');
if (irText) irText.innerHTML = t('helpIRText');
const categoriesTitle = document.getElementById('help-categories-title');
if (categoriesTitle) categoriesTitle.textContent = t('helpCategoriesTitle');
const versionText = document.getElementById('help-version');
if (versionText) versionText.innerHTML = t('helpVersion');
// Update category cards in Help modal
for (let i = 1; i <= 8; i++) {
const catName = document.getElementById(`help-cat-${i}-name`);
const catEx = document.getElementById(`help-cat-${i}-ex`);
if (catName) catName.textContent = `${i}. ${t(`helpCat${i}`)}`;
if (catEx) catEx.textContent = t(`helpCat${i}Ex`);
}
}
window.setLanguage = function(lang) {
state.language = lang;
localStorage.setItem('uae_lang', lang);
updateLanguage();
// Show toast
const langNames = { en: 'English', ar: 'العربية', cn: '中文' };
showToast(`Language: ${langNames[lang]}`, 'info');
};
// Initialize language on load
document.addEventListener('DOMContentLoaded', () => {
// Apply initial language
setTimeout(() => updateLanguage(), 100);
});
// Go to home page
window.goHome = function() {
// Reset state
state.currentQuery = '';
state.currentCategory = null;
state.results = [];
state.ratings = {};
state.translatedResults = {};
state.showOriginal = false;
// Clear inputs
if (DOM.searchInput) DOM.searchInput.value = '';
if (DOM.categoryText) DOM.categoryText.textContent = t('selectCategory');
// Switch to home mode
switchToHomeMode();
};
// Export for global access
window.selectCategory = selectCategory;
window.translateResults = translateResults;