{"id":193,"date":"2020-08-03T02:38:37","date_gmt":"2020-08-03T02:38:37","guid":{"rendered":"https:\/\/polloanalytics.com\/?page_id=193"},"modified":"2025-04-06T10:52:59","modified_gmt":"2025-04-06T14:52:59","slug":"unemployment-charts","status":"publish","type":"page","link":"https:\/\/polloanalytics.com\/index.php\/unemployment-charts\/","title":{"rendered":"Bateria Sim"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Bacteria Simulator<\/title>\n    <style>\n        body {\n            font-family: sans-serif;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            background-color: #f0f0f0;\n            margin: 0;\n            padding: 20px;\n            box-sizing: border-box;\n        }\n\n        #simulator-container {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 20px;\n            width: 100%;\n            max-width: 1200px; \/* Increased max-width slightly *\/\n            background-color: #fff;\n            padding: 20px;\n            border-radius: 8px;\n            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n        }\n\n        h1, h2 {\n            width: 100%;\n            text-align: center;\n            color: #333;\n            margin-top: 0;\n            margin-bottom: 15px;\n        }\n\n        #controls, #kpi {\n            flex: 1;\n            min-width: 280px; \/* Slightly wider *\/\n            padding: 15px;\n            border: 1px solid #ddd;\n            border-radius: 5px;\n            background-color: #f9f9f9;\n        }\n\n        #simulation-area {\n            flex: 2;\n            min-width: 400px;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n        }\n\n        #bacteria-canvas {\n            border: 1px solid #ccc;\n            background-color: #e9e9e9;\n            width: 100%; \/* Use JS to set actual width\/height *\/\n            max-width: 600px;\n            aspect-ratio: 1; \/* Maintain square shape *\/\n            display: block;\n            margin-top: 10px;\n        }\n\n        .control-group {\n            margin-bottom: 15px;\n        }\n\n        label {\n            display: block;\n            margin-bottom: 5px;\n            font-weight: bold;\n            color: #555;\n        }\n\n        input[type=\"range\"] {\n            width: 100%;\n            cursor: pointer;\n        }\n\n        .value-display {\n            font-weight: bold;\n            color: #007bff;\n        }\n\n        button {\n            padding: 10px 15px;\n            margin-right: 10px;\n            margin-bottom: 5px; \/* Ensure wrapping looks okay *\/\n            border: none;\n            border-radius: 4px;\n            cursor: pointer;\n            font-size: 1em;\n            transition: background-color 0.2s ease;\n        }\n        button:disabled {\n            background-color: #ccc;\n            cursor: not-allowed;\n        }\n        button:disabled:hover {\n             background-color: #ccc;\n        }\n\n\n        #start-button { background-color: #28a745; color: white; }\n        #start-button:hover:not(:disabled) { background-color: #218838; }\n        #pause-button { background-color: #ffc107; color: #333; }\n        #pause-button:hover:not(:disabled) { background-color: #e0a800; }\n        #reset-button { background-color: #dc3545; color: white; }\n        #reset-button:hover:not(:disabled) { background-color: #c82333; }\n\n        #kpi p {\n            margin: 8px 0;\n            color: #444;\n            line-height: 1.4;\n        }\n\n        #kpi span {\n            font-weight: bold;\n            color: #333;\n            min-width: 70px; \/* Adjusted min-width *\/\n            display: inline-block;\n            text-align: right; \/* Align numbers nicely *\/\n            margin-left: 5px;\n        }\n\n        #status {\n            font-style: italic;\n            margin-top: 10px;\n        }\n        #status.error { color: red; font-weight: bold; }\n        #status.warning { color: orange; }\n        #status.running { color: green; }\n        #status.paused { color: #666; }\n        #status.idle { color: #888; }\n\n    <\/style>\n<\/head>\n<body>\n    <h1>Bacteria Simulator<\/h1>\n\n    <div id=\"simulator-container\">\n\n        <div id=\"controls\">\n            <h2>Environment &#038; Controls<\/h2>\n            <div class=\"control-group\">\n                <label for=\"temperature\">Temperature (<span id=\"temp-value\" class=\"value-display\">50<\/span>\u00b0C)<\/label>\n                <input type=\"range\" id=\"temperature\" min=\"0\" max=\"100\" value=\"50\">\n            <\/div>\n            <div class=\"control-group\">\n                <label for=\"nutrients\">Nutrients (<span id=\"nutrient-value\" class=\"value-display\">50<\/span>%)<\/label>\n                <input type=\"range\" id=\"nutrients\" min=\"0\" max=\"100\" value=\"50\">\n            <\/div>\n             <div class=\"control-group\">\n                <label for=\"toxin\">Toxin Level (<span id=\"toxin-value\" class=\"value-display\">0<\/span> units)<\/label>\n                <input type=\"range\" id=\"toxin\" min=\"0\" max=\"100\" value=\"0\">\n            <\/div>\n            <hr style=\"margin: 20px 0;\">\n            <div class=\"control-group\">\n                <label for=\"simulationSpeed\">Simulation Speed (<span id=\"speed-value\" class=\"value-display\">5<\/span> ticks\/sec)<\/label>\n                <input type=\"range\" id=\"simulationSpeed\" min=\"1\" max=\"20\" value=\"5\"> <!-- Increased max speed -->\n             <\/div>\n             <hr>\n            <div>\n                <button id=\"start-button\">Start<\/button>\n                <button id=\"pause-button\">Pause<\/button>\n                <button id=\"reset-button\">Reset<\/button>\n            <\/div>\n             <p id=\"status\" class=\"idle\">Status: Idle<\/p>\n        <\/div>\n\n        <div id=\"simulation-area\">\n            <h2>Simulation Area<\/h2>\n            <canvas id=\"bacteria-canvas\" width=\"500\" height=\"500\"><\/canvas>\n            <p><small>Each dot represents a bacterium. Color indicates optimal temperature (Blue=Cold, Red=Hot). Brightness indicates fitness.<\/small><\/p>\n        <\/div>\n\n        <div id=\"kpi\">\n            <h2>Key Performance Indicators (KPIs)<\/h2>\n            <p>Population:<span id=\"population-count\">0<\/span><\/p>\n            <p>Max Population:<span id=\"max-population\">1000<\/span><\/p>\n            <p>Generation:<span id=\"generation-count\">0<\/span><\/p>\n            <p>Net Growth Rate:<span id=\"growth-rate\">N\/A<\/span> \/sec<\/p>\n            <hr style=\"margin: 10px 0;\">\n            <p>Avg. Fitness:<span id=\"avg-fitness\">N\/A<\/span><\/p>\n            <p>Avg. Optimal Temp:<span id=\"avg-opt-temp\">N\/A<\/span> \u00b0C<\/p>\n            <p>Avg. Optimal Nutrients:<span id=\"avg-opt-nutrients\">N\/A<\/span> %<\/p>\n            <p>Avg. Toxin Resist.:<span id=\"avg-opt-toxin\">N\/A<\/span> units<\/p>\n        <\/div>\n\n    <\/div>\n\n    <script>\n        \/\/ --- DOM Elements ---\n        const canvas = document.getElementById('bacteria-canvas');\n        const ctx = canvas.getContext('2d');\n\n        const tempSlider = document.getElementById('temperature');\n        const nutrientSlider = document.getElementById('nutrients');\n        const toxinSlider = document.getElementById('toxin'); \/\/ New\n        const speedSlider = document.getElementById('simulationSpeed');\n        const tempValueDisplay = document.getElementById('temp-value');\n        const nutrientValueDisplay = document.getElementById('nutrient-value');\n        const toxinValueDisplay = document.getElementById('toxin-value'); \/\/ New\n        const speedValueDisplay = document.getElementById('speed-value');\n\n        const startButton = document.getElementById('start-button');\n        const pauseButton = document.getElementById('pause-button');\n        const resetButton = document.getElementById('reset-button');\n\n        const populationDisplay = document.getElementById('population-count');\n        const generationDisplay = document.getElementById('generation-count');\n        const growthRateDisplay = document.getElementById('growth-rate'); \/\/ New\n        const avgOptTempDisplay = document.getElementById('avg-opt-temp');\n        const avgOptNutrientsDisplay = document.getElementById('avg-opt-nutrients');\n        const avgOptToxinDisplay = document.getElementById('avg-opt-toxin'); \/\/ New\n        const avgFitnessDisplay = document.getElementById('avg-fitness');\n        const maxPopulationDisplay = document.getElementById('max-population');\n        const statusDisplay = document.getElementById('status');\n\n        \/\/ --- Simulation Parameters ---\n        const MAX_POPULATION = 1000;\n        const INITIAL_POPULATION = 50;\n        const BACTERIA_RADIUS = 3;\n        const BASE_REPRODUCTION_RATE = 0.06; \/\/ Base chance per tick if fitness is 1\n        const BASE_DEATH_RATE = 0.01;       \/\/ Base chance per tick (non-fitness related)\n        const FITNESS_SENSITIVITY_DEATH = 3; \/\/ How much LOW fitness increases death rate\n        \/\/ const FITNESS_SENSITIVITY_REPRO = 1; \/\/ How much fitness impacts reproduction (already factored)\n        const TOXIN_LETHALITY = 0.3;        \/\/ How deadly toxins are (scales effect)\n        const MUTATION_RATE = 0.1;          \/\/ Chance of *any* mutation on reproduction\n        const MUTATION_STRENGTH_OPTIMAL = 5; \/\/ Max change in optimal value per mutation\n        const MUTATION_STRENGTH_TOLERANCE = 2;\/\/ Max change in tolerance per mutation\n        const AGE_FACTOR = 0.001;           \/\/ Additional death chance based on age per tick\n        const MAX_AGE = 150;                \/\/ Ticks until guaranteed death\n        const GROWTH_RATE_WINDOW_SECONDS = 2; \/\/ Calculate growth rate over this many seconds\n\n        \/\/ --- Simulation State ---\n        let bacteria = [];\n        let environment = {\n            temperature: parseInt(tempSlider.value),\n            nutrients: parseInt(nutrientSlider.value),\n            toxin: parseInt(toxinSlider.value) \/\/ New\n        };\n        let generation = 0;\n        let tickCount = 0;\n        let simulationInterval = null;\n        let simulationSpeed = parseInt(speedSlider.value); \/\/ Ticks per second\n        let simulationState = 'idle'; \/\/ idle, running, paused\n        let populationHistory = []; \/\/ For growth rate calculation {tick: count}\n\n        \/\/ --- Helper Functions ---\n        const getRandom = (min, max) => Math.random() * (max - min) + min;\n        const clamp = (value, min, max) => Math.max(min, Math.min(value, max));\n\n        \/\/ --- Bacteria Object ---\n        function createBacterium(parent = null) {\n            const id = Date.now().toString(36) + Math.random().toString(36).substring(2);\n            let optimalTemperature, optimalNutrients, optimalToxinResistance;\n            let tempTolerance, nutrientTolerance, toxinTolerance;\n\n            if (parent) {\n                optimalTemperature = parent.optimalTemperature;\n                optimalNutrients = parent.optimalNutrients;\n                optimalToxinResistance = parent.optimalToxinResistance; \/\/ Inherit\n                tempTolerance = parent.tempTolerance;\n                nutrientTolerance = parent.nutrientTolerance;\n                toxinTolerance = parent.toxinTolerance; \/\/ Inherit\n\n                \/\/ --- Mutation ---\n                if (Math.random() < MUTATION_RATE) { \/\/ Temperature Optimal\n                    optimalTemperature += getRandom(-MUTATION_STRENGTH_OPTIMAL, MUTATION_STRENGTH_OPTIMAL);\n                    optimalTemperature = clamp(optimalTemperature, 0, 100);\n                }\n                if (Math.random() < MUTATION_RATE) { \/\/ Nutrients Optimal\n                    optimalNutrients += getRandom(-MUTATION_STRENGTH_OPTIMAL, MUTATION_STRENGTH_OPTIMAL);\n                    optimalNutrients = clamp(optimalNutrients, 0, 100);\n                }\n                 if (Math.random() < MUTATION_RATE) { \/\/ Toxin Resistance Optimal\n                    optimalToxinResistance += getRandom(-MUTATION_STRENGTH_OPTIMAL, MUTATION_STRENGTH_OPTIMAL);\n                    optimalToxinResistance = clamp(optimalToxinResistance, 0, 100); \/\/ Can adapt to resist 0 to 100 toxin levels\n                }\n\n                \/\/ --- Tolerance Mutation (less frequent or impactful) ---\n                 if (Math.random() < MUTATION_RATE \/ 2) { \/\/ Temp Tolerance\n                    tempTolerance += getRandom(-MUTATION_STRENGTH_TOLERANCE, MUTATION_STRENGTH_TOLERANCE);\n                    tempTolerance = clamp(tempTolerance, 5, 50); \/\/ Min\/Max tolerance range\n                 }\n                 if (Math.random() < MUTATION_RATE \/ 2) { \/\/ Nutrient Tolerance\n                    nutrientTolerance += getRandom(-MUTATION_STRENGTH_TOLERANCE, MUTATION_STRENGTH_TOLERANCE);\n                    nutrientTolerance = clamp(nutrientTolerance, 5, 50);\n                 }\n                 if (Math.random() < MUTATION_RATE \/ 2) { \/\/ Toxin Tolerance\n                    toxinTolerance += getRandom(-MUTATION_STRENGTH_TOLERANCE, MUTATION_STRENGTH_TOLERANCE);\n                    toxinTolerance = clamp(toxinTolerance, 5, 50); \/\/ How wide a range of toxin levels it tolerates around its optimal\n                 }\n\n            } else {\n                \/\/ Initial bacterium values\n                optimalTemperature = getRandom(30, 70);\n                optimalNutrients = getRandom(30, 70);\n                optimalToxinResistance = getRandom(0, 20); \/\/ Start with low resistance generally\n                tempTolerance = getRandom(10, 30);\n                nutrientTolerance = getRandom(10, 30);\n                toxinTolerance = getRandom(10, 25); \/\/ Start with moderate toxin tolerance range\n            }\n\n            return {\n                id: id,\n                x: getRandom(BACTERIA_RADIUS, canvas.width - BACTERIA_RADIUS),\n                y: getRandom(BACTERIA_RADIUS, canvas.height - BACTERIA_RADIUS),\n                age: 0,\n                maxAge: MAX_AGE + getRandom(-MAX_AGE*0.2, MAX_AGE*0.2),\n                optimalTemperature: optimalTemperature,\n                optimalNutrients: optimalNutrients,\n                optimalToxinResistance: optimalToxinResistance, \/\/ New\n                tempTolerance: tempTolerance,\n                nutrientTolerance: nutrientTolerance,\n                toxinTolerance: toxinTolerance, \/\/ New\n                fitness: 0 \/\/ Based on Temp\/Nutrients for reproduction\n            };\n        }\n\n        \/\/ --- Simulation Core Logic ---\n        function calculateFitness(bacterium) {\n            \/\/ Fitness primarily based on temperature and nutrients for reproduction suitability\n            const tempDiff = Math.abs(environment.temperature - bacterium.optimalTemperature);\n            const nutrientDiff = Math.abs(environment.nutrients - bacterium.optimalNutrients);\n\n            const tempFactor = clamp(1 - (tempDiff \/ bacterium.tempTolerance), 0, 1);\n            const nutrientFactor = clamp(1 - (nutrientDiff \/ bacterium.nutrientTolerance), 0, 1);\n\n            \/\/ Average factor - both contribute equally\n            return clamp( (tempFactor + nutrientFactor) \/ 2, 0.01, 1);\n        }\n\n         function calculateToxinResistanceFactor(bacterium) {\n             \/\/ How well the bacterium resists the CURRENT toxin level\n             const toxinDiff = Math.abs(environment.toxin - bacterium.optimalToxinResistance);\n             \/\/ Higher tolerance means it handles a wider range of toxin levels around its optimal\n             const resistanceFactor = clamp(1 - (toxinDiff \/ bacterium.toxinTolerance), 0, 1);\n             return resistanceFactor; \/\/ 1 = perfectly resistant, 0 = no resistance to current level\n         }\n\n        function updateSimulation() {\n            if (simulationState !== 'running') return;\n\n            const newBacteria = [];\n            const diedBacteriaIndices = [];\n\n            \/\/ Iterate backwards for safe removal during loop\n            for (let i = bacteria.length - 1; i >= 0; i--) {\n                const bacterium = bacteria[i];\n                bacterium.age++;\n\n                \/\/ Calculate fitness (for reproduction) based on Temp\/Nutrients\n                bacterium.fitness = calculateFitness(bacterium);\n\n                \/\/ Calculate resistance to current toxin level (for survival)\n                const toxinResistanceFactor = calculateToxinResistanceFactor(bacterium);\n\n                \/\/ --- Reproduction ---\n                \/\/ Chance increases with fitness, decreases as population nears max\n                const carryingCapacityFactor = Math.max(0, (1 - bacteria.length \/ MAX_POPULATION)); \/\/ 0 when full\n                const reproductionChance = BASE_REPRODUCTION_RATE * bacterium.fitness * carryingCapacityFactor;\n\n                if (Math.random() < reproductionChance &#038;&#038; bacteria.length + newBacteria.length < MAX_POPULATION) {\n                    newBacteria.push(createBacterium(bacterium));\n                }\n\n                \/\/ --- Death ---\n                \/\/ Factors: Base rate, Age, Low Temp\/Nutrient Fitness, Toxin Exposure\n                const ageDeathFactor = (bacterium.age \/ bacterium.maxAge) * AGE_FACTOR;\n\n                \/\/ Increased death from mismatch with temp\/nutrients\n                const fitnessDeathFactor = (1 - bacterium.fitness) * FITNESS_SENSITIVITY_DEATH * BASE_DEATH_RATE;\n\n                \/\/ Increased death from toxin exposure, mitigated by resistance\n                const toxinExposureEffect = environment.toxin \/ 100; \/\/ 0 to 1 scale\n                const lackOfResistance = (1 - toxinResistanceFactor); \/\/ 0 to 1 scale\n                const toxinDeathFactor = toxinExposureEffect * lackOfResistance * TOXIN_LETHALITY;\n\n                \/\/ Total death chance\n                const deathChance = clamp(BASE_DEATH_RATE + ageDeathFactor + fitnessDeathFactor + toxinDeathFactor, 0, 1);\n\n                if (Math.random() < deathChance || bacterium.age >= bacterium.maxAge) {\n                    diedBacteriaIndices.push(i);\n                } else {\n                     \/\/ Simple movement\n                    bacterium.x += getRandom(-1, 1);\n                    bacterium.y += getRandom(-1, 1);\n                    bacterium.x = clamp(bacterium.x, BACTERIA_RADIUS, canvas.width - BACTERIA_RADIUS);\n                    bacterium.y = clamp(bacterium.y, BACTERIA_RADIUS, canvas.height - BACTERIA_RADIUS);\n                }\n            }\n\n            \/\/ Remove dead bacteria efficiently\n             diedBacteriaIndices.sort((a, b) => b - a); \/\/ Sort descending\n             for (const index of diedBacteriaIndices) {\n                 bacteria.splice(index, 1);\n             }\n\n            \/\/ Add new bacteria\n            bacteria = bacteria.concat(newBacteria);\n\n            \/\/ Increment counters\n            generation++;\n            tickCount++;\n\n             \/\/ Record population history for growth rate calculation\n             populationHistory.push({ tick: tickCount, count: bacteria.length });\n             \/\/ Keep history within a reasonable limit (e.g., slightly more than needed for rate calc)\n             const historyLimit = simulationSpeed * (GROWTH_RATE_WINDOW_SECONDS + 1);\n             if (populationHistory.length > historyLimit) {\n                 populationHistory.shift(); \/\/ Remove the oldest entry\n             }\n\n            \/\/ Update visuals and KPIs\n            drawSimulation();\n            updateKPI();\n\n            \/\/ Check for extinction or max population\n            if (bacteria.length === 0 && simulationState === 'running') { \/\/ Ensure we don't trigger this on reset\n                pauseSimulation();\n                 updateStatus(\"Extinct! Population reached zero.\", \"error\");\n            } else if (bacteria.length >= MAX_POPULATION) {\n                 updateStatus(\"Max Population Reached\", \"warning\");\n                 \/\/ Don't pause, just let carrying capacity limit growth\n            } else if (simulationState === 'running') {\n                 \/\/ If running and no other status, keep showing \"Running\"\n                 updateStatus(\"Running\", \"running\");\n            }\n        }\n\n        \/\/ --- Drawing ---\n        function drawSimulation() {\n            \/\/ Clear canvas\n            ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n            \/\/ Draw background (subtly indicate toxin level? e.g. slight purple tint)\n            const toxinColorIntensity = Math.round(environment.toxin * 1.0); \/\/ 0-100\n            const nutrientColorIntensity = Math.round(environment.nutrients * 0.5); \/\/ 0-50\n            \/\/ Base grey, add green for nutrients, purple for toxin\n             ctx.fillStyle = `rgb(${230 - toxinColorIntensity * 0.3}, ${230 - nutrientColorIntensity * 0.2}, ${230 - toxinColorIntensity * 0.1})`;\n            ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n            \/\/ Draw bacteria\n            bacteria.forEach(bacterium => {\n                \/\/ Color based on optimal temperature (Blue=Cold, Red=Hot)\n                const tempRatio = bacterium.optimalTemperature \/ 100;\n                const r = Math.round(255 * tempRatio);\n                const b = Math.round(255 * (1 - tempRatio));\n                const g = 50;\n\n                \/\/ Use fitness (temp\/nutrient based) to affect alpha\/brightness\n                \/\/ Add a minimum brightness so they don't disappear completely if fitness is low\n                const alpha = clamp(bacterium.fitness, 0.2, 1.0);\n\n                ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${alpha})`;\n\n                ctx.beginPath();\n                ctx.arc(bacterium.x, bacterium.y, BACTERIA_RADIUS, 0, Math.PI * 2);\n                ctx.fill();\n            });\n        }\n\n        \/\/ --- KPI Update ---\n        function updateKPI() {\n            populationDisplay.textContent = bacteria.length;\n            generationDisplay.textContent = generation;\n            maxPopulationDisplay.textContent = MAX_POPULATION;\n\n            \/\/ Calculate Net Growth Rate\n            const targetTicksAgo = simulationSpeed * GROWTH_RATE_WINDOW_SECONDS;\n            const oldestRelevantTick = tickCount - targetTicksAgo;\n            const startPoint = populationHistory.find(p => p.tick >= oldestRelevantTick);\n\n            if (startPoint && populationHistory.length > 1 && tickCount > targetTicksAgo) {\n                const currentPop = bacteria.length;\n                const previousPop = startPoint.count;\n                const ticksElapsed = tickCount - startPoint.tick;\n                const secondsElapsed = ticksElapsed \/ simulationSpeed;\n                if (secondsElapsed > 0) {\n                    const ratePerSecond = (currentPop - previousPop) \/ secondsElapsed;\n                    growthRateDisplay.textContent = ratePerSecond.toFixed(1);\n                } else {\n                    growthRateDisplay.textContent = \"Calc...\";\n                }\n            } else if (bacteria.length > 0) {\n                 growthRateDisplay.textContent = \"Calc...\"; \/\/ Not enough data yet\n            }\n            else {\n                 growthRateDisplay.textContent = \"0.0\";\n            }\n\n\n            \/\/ Calculate Averages\n            if (bacteria.length > 0) {\n                let sumOptTemp = 0;\n                let sumOptNutrients = 0;\n                let sumOptToxinResist = 0;\n                let sumFitness = 0;\n                bacteria.forEach(b => {\n                    sumOptTemp += b.optimalTemperature;\n                    sumOptNutrients += b.optimalNutrients;\n                    sumOptToxinResist += b.optimalToxinResistance;\n                    sumFitness += b.fitness; \/\/ Temp\/Nutrient fitness\n                });\n                const avgTemp = (sumOptTemp \/ bacteria.length).toFixed(1);\n                const avgNutrients = (sumOptNutrients \/ bacteria.length).toFixed(1);\n                const avgToxin = (sumOptToxinResist \/ bacteria.length).toFixed(1);\n                const avgFitness = (sumFitness \/ bacteria.length).toFixed(3);\n\n                avgOptTempDisplay.textContent = avgTemp;\n                avgOptNutrientsDisplay.textContent = avgNutrients;\n                avgOptToxinDisplay.textContent = avgToxin;\n                avgFitnessDisplay.textContent = avgFitness;\n            } else {\n                avgOptTempDisplay.textContent = \"N\/A\";\n                avgOptNutrientsDisplay.textContent = \"N\/A\";\n                avgOptToxinDisplay.textContent = \"N\/A\";\n                avgFitnessDisplay.textContent = \"N\/A\";\n                 growthRateDisplay.textContent = \"0.0\";\n            }\n        }\n\n        \/\/ --- Status Update ---\n        function updateStatus(message, type = 'info') {\n            statusDisplay.textContent = `Status: ${message}`;\n            statusDisplay.className = type; \/\/ Add class for styling (idle, running, paused, warning, error)\n        }\n\n\n        \/\/ --- Control Functions ---\n        function startSimulation() {\n            if (simulationState === 'running') return;\n\n            if (simulationState === 'idle') {\n                 resetSimulation(); \/\/ Ensure clean start if starting from idle\n            }\n\n            simulationState = 'running';\n            updateStatus(\"Running\", \"running\");\n\n            if (simulationInterval) clearInterval(simulationInterval); \/\/ Clear just in case\n\n             const intervalDuration = 1000 \/ simulationSpeed;\n             simulationInterval = setInterval(updateSimulation, intervalDuration);\n\n            startButton.disabled = true;\n            pauseButton.disabled = false;\n            resetButton.disabled = false;\n        }\n\n        function pauseSimulation() {\n             \/\/ Allow pausing even if extinct message is shown\n            if (simulationState !== 'running') return;\n\n            simulationState = 'paused';\n             \/\/ Keep the last status message unless it was just 'Running'\n             if (statusDisplay.textContent === 'Status: Running') {\n                updateStatus(\"Paused\", \"paused\");\n             } else {\n                 \/\/ Keep the existing status (e.g., \"Extinct\", \"Max Pop\") but mark state as paused\n                 \/\/ No visual status text change needed here, just internal state.\n             }\n\n\n             if (simulationInterval) clearInterval(simulationInterval);\n             simulationInterval = null;\n\n            startButton.disabled = false; \/\/ Allow restart\/resume\n            pauseButton.disabled = true;\n        }\n\n        function resetSimulation() {\n            if (simulationInterval) clearInterval(simulationInterval);\n            simulationInterval = null;\n\n            simulationState = 'idle';\n            updateStatus(\"Idle\", \"idle\");\n\n            \/\/ Reset variables\n            bacteria = [];\n            generation = 0;\n            tickCount = 0;\n            populationHistory = []; \/\/ Clear history\n            environment.temperature = parseInt(tempSlider.value);\n            environment.nutrients = parseInt(nutrientSlider.value);\n            environment.toxin = parseInt(toxinSlider.value);\n\n            \/\/ Create initial population\n            for (let i = 0; i < INITIAL_POPULATION; i++) {\n                \/\/ Ensure canvas dimensions are set before creating bacteria that depend on them\n                if (canvas.width > 0 && canvas.height > 0) {\n                    bacteria.push(createBacterium());\n                } else {\n                    console.warn(\"Canvas dimensions not set during initial population creation.\");\n                }\n            }\n             \/\/ Initial population record\n             populationHistory.push({ tick: 0, count: bacteria.length });\n\n            \/\/ Update displays\n            updateKPI();\n            drawSimulation();\n\n            startButton.disabled = false;\n            pauseButton.disabled = true;\n            resetButton.disabled = true; \/\/ Disable reset until started\n        }\n\n         function changeSpeed() {\n             simulationSpeed = parseInt(speedSlider.value);\n             speedValueDisplay.textContent = simulationSpeed;\n             if (simulationState === 'running') {\n                 clearInterval(simulationInterval);\n                 const intervalDuration = 1000 \/ simulationSpeed;\n                 simulationInterval = setInterval(updateSimulation, intervalDuration);\n             }\n             \/\/ Adjust population history window if needed based on new speed?\n             \/\/ Maybe not necessary if we keep a fixed number of seconds history\n         }\n\n        \/\/ --- Event Listeners ---\n        tempSlider.addEventListener('input', (e) => {\n            environment.temperature = parseInt(e.target.value);\n            tempValueDisplay.textContent = environment.temperature;\n        });\n\n        nutrientSlider.addEventListener('input', (e) => {\n            environment.nutrients = parseInt(e.target.value);\n            nutrientValueDisplay.textContent = environment.nutrients;\n            drawSimulation(); \/\/ Redraw background if nutrient influences it\n        });\n\n        toxinSlider.addEventListener('input', (e) => { \/\/ New\n            environment.toxin = parseInt(e.target.value);\n            toxinValueDisplay.textContent = environment.toxin;\n            drawSimulation(); \/\/ Redraw background if toxin influences it\n        });\n\n        speedSlider.addEventListener('input', changeSpeed);\n\n        startButton.addEventListener('click', startSimulation);\n        pauseButton.addEventListener('click', pauseSimulation);\n        resetButton.addEventListener('click', resetSimulation);\n\n        \/\/ --- Initialization ---\n        function initialize() {\n            \/\/ Set initial display values from sliders\n            tempValueDisplay.textContent = tempSlider.value;\n            nutrientValueDisplay.textContent = nutrientSlider.value;\n            toxinValueDisplay.textContent = toxinSlider.value; \/\/ New\n            speedValueDisplay.textContent = speedSlider.value;\n\n            \/\/ Set canvas size\n            const simAreaWidth = document.getElementById('simulation-area').offsetWidth;\n            const canvasSize = Math.min(500, simAreaWidth > 50 ? simAreaWidth - 40 : 500); \/\/ Ensure positive size\n            canvas.width = canvasSize > 0 ? canvasSize : 500; \/\/ Fallback size\n            canvas.height = canvasSize > 0 ? canvasSize : 500;\n\n            resetSimulation(); \/\/ Set up the initial state\n        }\n\n        \/\/ Wait for the DOM to be fully loaded before initializing\n        document.addEventListener('DOMContentLoaded', initialize);\n\n         \/\/ Handle window resize to potentially adjust canvas size? (Optional)\n         \/\/ window.addEventListener('resize', () => {\n         \/\/    \/\/ Debounce this if implemented\n         \/\/    const simAreaWidth = document.getElementById('simulation-area').offsetWidth;\n         \/\/    const canvasSize = Math.min(500, simAreaWidth - 40);\n         \/\/    if (canvas.width !== canvasSize) {\n         \/\/       canvas.width = canvasSize;\n         \/\/       canvas.height = canvasSize;\n         \/\/       if (simulationState !== 'running') { \/\/ Avoid redrawing if actively running?\n         \/\/          drawSimulation();\n         \/\/       }\n         \/\/    }\n         \/\/ });\n\n    <\/script>\n\n<\/body>\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bacteria Simulator Bacteria Simulator Environment &#038; Controls Temperature (50\u00b0C) Nutrients (50%) Toxin Level (0 units) Simulation Speed (5 ticks\/sec) Start Pause Reset Status: Idle Simulation Area Each dot represents a bacterium. Color indicates optimal temperature (Blue=Cold, Red=Hot). Brightness indicates fitness. Key Performance Indicators (KPIs) Population:0 Max Population:1000 Generation:0 Net Growth Rate:N\/A \/sec Avg. Fitness:N\/A Avg. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-193","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/pages\/193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/comments?post=193"}],"version-history":[{"count":11,"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/pages\/193\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/pages\/193\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/polloanalytics.com\/index.php\/wp-json\/wp\/v2\/media?parent=193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}