Changed around line 1
+ class MediScan {
+ constructor() {
+ this.config = {
+ photo_model: process.env.PHOTO_MODEL,
+ photo_prompt: process.env.PHOTO_PROMPT,
+ photo_base_url: process.env.PHOTO_BASE_URL,
+ photo_api_key: process.env.PHOTO_API_KEY,
+ photo_max_tokens: process.env.PHOTO_MAX_TOKENS,
+ photo_temperature: process.env.PHOTO_TEMPERATURE,
+ text_model: process.env.TEXT_MODEL,
+ text_prompt: process.env.TEXT_PROMPT,
+ text_base_url: process.env.TEXT_BASE_URL,
+ text_api_key: process.env.TEXT_API_KEY,
+ text_max_tokens: process.env.TEXT_MAX_TOKENS,
+ text_temperature: process.env.TEXT_TEMPERATURE
+ };
+
+ this.selectedFiles = [];
+ this.initializeElements();
+ this.attachEventListeners();
+ }
+
+ initializeElements() {
+ this.fileInput = document.getElementById('fileInput');
+ this.uploadBox = document.getElementById('uploadBox');
+ this.previewContainer = document.getElementById('previewContainer');
+ this.analyzeBtn = document.getElementById('analyzeBtn');
+ this.resultSection = document.getElementById('resultSection');
+ this.loadingSpinner = document.getElementById('loadingSpinner');
+ this.resultContainer = document.getElementById('resultContainer');
+ this.resultContent = document.getElementById('resultContent');
+ }
+
+ attachEventListeners() {
+ this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
+ this.analyzeBtn.addEventListener('click', () => this.analyzePrescriptions());
+ }
+
+ handleFileSelect(event) {
+ const files = Array.from(event.target.files);
+ this.selectedFiles = files;
+ this.previewContainer.innerHTML = '';
+
+ files.forEach(file => {
+ if (file.type.startsWith('image/')) {
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ const img = document.createElement('img');
+ img.src = e.target.result;
+ img.classList.add('preview-image');
+ this.previewContainer.appendChild(img);
+ };
+ reader.readAsDataURL(file);
+ }
+ });
+
+ this.analyzeBtn.disabled = files.length === 0;
+ }
+
+ async analyzePrescriptions() {
+ try {
+ this.showLoading();
+
+ // Convert images to base64
+ const imagePromises = this.selectedFiles.map(file => this.fileToBase64(file));
+ const base64Images = await Promise.all(imagePromises);
+
+ // Process images with vision model
+ const imageAnalysisPromises = base64Images.map(image =>
+ this.processWithVisionModel(image)
+ );
+ const imageResults = await Promise.all(imageAnalysisPromises);
+
+ // Process results with language model
+ const finalAnalysis = await this.processWithLanguageModel(imageResults);
+
+ this.displayResults(finalAnalysis);
+ } catch (error) {
+ console.error('Analysis failed:', error);
+ this.displayError('Analysis failed. Please try again.');
+ } finally {
+ this.hideLoading();
+ }
+ }
+
+ fileToBase64(file) {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => resolve(reader.result.split(',')[1]);
+ reader.onerror = reject;
+ reader.readAsDataURL(file);
+ });
+ }
+
+ async processWithVisionModel(base64Image) {
+ // Implementation would depend on the specific API being used
+ // This is a placeholder for the actual API call
+ return fetch(this.config.photo_base_url, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${this.config.photo_api_key}`,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ model: this.config.photo_model,
+ prompt: this.config.photo_prompt,
+ image: base64Image,
+ max_tokens: this.config.photo_max_tokens,
+ temperature: this.config.photo_temperature
+ })
+ }).then(response => response.json());
+ }
+
+ async processWithLanguageModel(imageResults) {
+ // Implementation would depend on the specific API being used
+ // This is a placeholder for the actual API call
+ return fetch(this.config.text_base_url, {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${this.config.text_api_key}`,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ model: this.config.text_model,
+ prompt: this.config.text_prompt,
+ messages: [{
+ role: 'user',
+ content: JSON.stringify(imageResults)
+ }],
+ max_tokens: this.config.text_max_tokens,
+ temperature: this.config.text_temperature
+ })
+ }).then(response => response.json());
+ }
+
+ showLoading() {
+ this.resultSection.style.display = 'block';
+ this.loadingSpinner.style.display = 'block';
+ this.resultContainer.style.display = 'none';
+ }
+
+ hideLoading() {
+ this.loadingSpinner.style.display = 'none';
+ this.resultContainer.style.display = 'block';
+ }
+
+ displayResults(analysis) {
+ this.resultContent.innerHTML = `
+
+
Prescription Analysis
+
${analysis.result || analysis.choices[0].message.content}
+
+ `;
+ }
+
+ displayError(message) {
+ this.resultContent.innerHTML = `
+ `;
+ }
+ }
+
+ // Initialize the application
+ document.addEventListener('DOMContentLoaded', () => {
+ new MediScan();
+ });