{"id":"sdsqni","deleted":false,"future_paste":false,"expired":false,"language":"html","created_at":"2026-09-09 07:49:00","expires_at":null,"content":"<!DOCTYPE html>\r\n<html lang=\"de\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>KORG Kaoscillator - Digital Hardcore (Low-Latency)<\/title>\r\n    <style>\r\n        :root {\r\n            --bg-color: #0d0d0d;\r\n            --panel-bg: #18181f;\r\n            --accent-yellow: #ffcc00;\r\n            --accent-red: #ff3333;\r\n        }\r\n\r\n        body {\r\n            background-color: var(--bg-color);\r\n            color: #fff;\r\n            font-family: 'Courier New', Courier, monospace;\r\n            display: flex;\r\n            justify-content: center;\r\n            align-items: center;\r\n            min-height: 100vh;\r\n            margin: 0;\r\n            user-select: none;\r\n        }\r\n\r\n        .kaoss-container {\r\n            background: var(--panel-bg);\r\n            border: 4px solid #333;\r\n            border-radius: 16px;\r\n            padding: 20px;\r\n            box-shadow: 0 10px 30px rgba(0,0,0,0.9), inset 0 0 15px rgba(255,255,255,0.05);\r\n            width: 380px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 12px;\r\n        }\r\n\r\n        .header {\r\n            display: flex;\r\n            justify-content: space-between;\r\n            align-items: center;\r\n            border-bottom: 2px solid #333;\r\n            padding-bottom: 6px;\r\n        }\r\n\r\n        .title {\r\n            font-weight: bold;\r\n            font-size: 1.1rem;\r\n            color: var(--accent-yellow);\r\n            letter-spacing: 2px;\r\n        }\r\n\r\n        .subtitle {\r\n            font-size: 0.65rem;\r\n            color: var(--accent-red);\r\n            font-weight: bold;\r\n        }\r\n\r\n        .display {\r\n            background: #000;\r\n            border: 2px solid #444;\r\n            border-radius: 6px;\r\n            padding: 8px 12px;\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 4px;\r\n            font-family: monospace;\r\n            color: var(--accent-yellow);\r\n            text-shadow: 0 0 5px var(--accent-yellow);\r\n            font-size: 0.85rem;\r\n        }\r\n\r\n        .display-row {\r\n            display: flex;\r\n            justify-content: space-between;\r\n        }\r\n\r\n        .pad-container {\r\n            position: relative;\r\n            width: 100%;\r\n            height: 260px;\r\n            background: #050505;\r\n            border: 3px solid #444;\r\n            border-radius: 12px;\r\n            overflow: hidden;\r\n            cursor: crosshair;\r\n            touch-action: none;\r\n        }\r\n\r\n        canvas {\r\n            width: 100%;\r\n            height: 100%;\r\n        }\r\n\r\n        .controls {\r\n            display: grid;\r\n            grid-template-columns: 1fr 1fr;\r\n            gap: 8px;\r\n        }\r\n\r\n        .control-group {\r\n            display: flex;\r\n            flex-direction: column;\r\n            gap: 3px;\r\n        }\r\n\r\n        label {\r\n            font-size: 0.65rem;\r\n            color: #aaa;\r\n            text-transform: uppercase;\r\n            font-weight: bold;\r\n        }\r\n\r\n        select, button, input {\r\n            background: #252530;\r\n            color: #fff;\r\n            border: 1px solid #444;\r\n            padding: 6px;\r\n            border-radius: 4px;\r\n            font-family: inherit;\r\n            font-size: 0.78rem;\r\n            font-weight: bold;\r\n            cursor: pointer;\r\n        }\r\n\r\n        select:focus, button:focus, input:focus {\r\n            outline: none;\r\n            border-color: var(--accent-yellow);\r\n        }\r\n\r\n        button.active {\r\n            background: var(--accent-red);\r\n            color: #fff;\r\n            box-shadow: 0 0 10px var(--accent-red);\r\n        }\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n\r\n<div class=\"kaoss-container\">\r\n    <div class=\"header\">\r\n        <div class=\"title\">KAOSS-DHC<\/div>\r\n        <div class=\"subtitle\">ZERO-LATENCY EDITION<\/div>\r\n    <\/div>\r\n\r\n    <div class=\"display\">\r\n        <div class=\"display-row\">\r\n            <span id=\"disp-preset\">SYNTH: DHC SAW<\/span>\r\n            <span id=\"disp-bpm\">180 BPM<\/span>\r\n        <\/div>\r\n        <div class=\"display-row\">\r\n            <span id=\"disp-scale\">SKALA: PHRYGIAN DOM<\/span>\r\n            <span id=\"disp-pattern\">BEAT: DHC BREAK<\/span>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"pad-container\" id=\"pad\">\r\n        <canvas id=\"visualizer\"><\/canvas>\r\n    <\/div>\r\n\r\n    <div class=\"controls\">\r\n        <div class=\"control-group\">\r\n            <label for=\"preset\">Preset<\/label>\r\n            <select id=\"preset\">\r\n                <option value=\"saw\">Aggro Saw Lead<\/option>\r\n                <option value=\"acid\">Screaming 303<\/option>\r\n                <option value=\"sub\">Distorted Sub<\/option>\r\n                <option value=\"noise\">Cyber Chaos<\/option>\r\n            <\/select>\r\n        <\/div>\r\n\r\n        <div class=\"control-group\">\r\n            <label for=\"scale\">Skala (Exotisch)<\/label>\r\n            <select id=\"scale\">\r\n                <option value=\"phrygianDom\">Phrygisch-Dominant<\/option>\r\n                <option value=\"hirajoshi\">Hirajoshi (Japan)<\/option>\r\n                <option value=\"hungarianMin\">Ungarisch Moll<\/option>\r\n                <option value=\"arabic\">Arabisch (Bayati)<\/option>\r\n                <option value=\"pelog\">Pelog (Bali)<\/option>\r\n                <option value=\"minor\">Min-Pentatonisch<\/option>\r\n                <option value=\"blues\">Blues<\/option>\r\n                <option value=\"chromatic\">Chromatisch<\/option>\r\n                <option value=\"raw\">Unquantisiert<\/option>\r\n            <\/select>\r\n        <\/div>\r\n\r\n        <div class=\"control-group\">\r\n            <label for=\"beat-pattern\">Drum Pattern<\/label>\r\n            <select id=\"beat-pattern\">\r\n                <option value=\"dhc\">DHC Breakbeat<\/option>\r\n                <option value=\"amen\">Amen Cyber Cut<\/option>\r\n                <option value=\"gabber\">Gabber 4-to-Floor<\/option>\r\n                <option value=\"industrial\">Industrial Sync<\/option>\r\n                <option value=\"speedcore\">Speedcore Terror<\/option>\r\n            <\/select>\r\n        <\/div>\r\n\r\n        <div class=\"control-group\">\r\n            <label for=\"bpm\">Tempo \/ Beat<\/label>\r\n            <div style=\"display: flex; gap: 4px;\">\r\n                <input type=\"number\" id=\"bpm\" value=\"180\" min=\"120\" max=\"240\" style=\"width: 45%;\">\r\n                <button id=\"beat-btn\" style=\"width: 55%;\">BEAT RUN<\/button>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n<\/div>\r\n\r\n<script>\r\n    let audioCtx = null;\r\n    let masterGain, driveNode, filterNode, mainOsc, subOsc;\r\n    let noiseBuffer = null;\r\n    let isTouching = false;\r\n    let beatPlaying = false;\r\n\r\n    \/\/ Scheduler Variables (Low Latency Web Audio Clock)\r\n    let lookahead = 25.0; \/\/ ms\r\n    let scheduleAheadTime = 0.1; \/\/ seconds\r\n    let nextNoteTime = 0.0;\r\n    let current16thNote = 0;\r\n    let timerID = null;\r\n\r\n    const baseFreq = 110; \/\/ A2\r\n\r\n    \/\/ Exotic & Standard Scales\r\n    const scales = {\r\n        phrygianDom:  [0, 1, 4, 5, 7, 8, 10, 12, 13, 16, 17, 19, 20, 22, 24],\r\n        hirajoshi:    [0, 2, 3, 7, 8, 12, 14, 15, 19, 20, 24],\r\n        hungarianMin: [0, 2, 3, 6, 7, 8, 11, 12, 14, 15, 18, 19, 20, 23, 24],\r\n        arabic:       [0, 1, 4, 5, 7, 8, 11, 12, 13, 16, 17, 19, 20, 23, 24],\r\n        pelog:        [0, 1, 3, 7, 8, 12, 13, 15, 19, 20, 24],\r\n        minor:        [0, 3, 5, 7, 10, 12, 15, 17, 19, 22, 24],\r\n        blues:        [0, 3, 5, 6, 7, 10, 12, 15, 17, 18, 19, 22, 24],\r\n        chromatic:    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]\r\n    };\r\n\r\n    \/\/ 16-step Drum Patterns\r\n    const drumPatterns = {\r\n        dhc: {\r\n            kick:  [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0],\r\n            snare: [0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0],\r\n            hat:   [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0]\r\n        },\r\n        amen: {\r\n            kick:  [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],\r\n            snare: [0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1],\r\n            hat:   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\r\n        },\r\n        gabber: {\r\n            kick:  [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],\r\n            snare: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],\r\n            hat:   [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0]\r\n        },\r\n        industrial: {\r\n            kick:  [1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0],\r\n            snare: [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0],\r\n            hat:   [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]\r\n        },\r\n        speedcore: {\r\n            kick:  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],\r\n            snare: [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0],\r\n            hat:   [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]\r\n        }\r\n    };\r\n\r\n    function initAudio() {\r\n        if (audioCtx) return;\r\n        audioCtx = new (window.AudioContext || window.webkitAudioContext)({ latencyHint: 'interactive' });\r\n\r\n        masterGain = audioCtx.createGain();\r\n        masterGain.gain.value = 0.3;\r\n\r\n        \/\/ Hardcore Overdrive Distortion Node\r\n        driveNode = audioCtx.createWaveShaper();\r\n        driveNode.curve = makeDistortionCurve(95);\r\n        driveNode.oversample = '4x';\r\n\r\n        \/\/ Filter Node\r\n        filterNode = audioCtx.createBiquadFilter();\r\n        filterNode.type = 'lowpass';\r\n        filterNode.frequency.value = 2000;\r\n        filterNode.Q.value = 6;\r\n\r\n        filterNode.connect(driveNode);\r\n        driveNode.connect(masterGain);\r\n        masterGain.connect(audioCtx.destination);\r\n\r\n        \/\/ Pre-generate noise buffer to avoid audio thread stalls\r\n        createNoiseBuffer();\r\n    }\r\n\r\n    function createNoiseBuffer() {\r\n        const bufferSize = audioCtx.sampleRate * 1.0;\r\n        noiseBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);\r\n        const output = noiseBuffer.getChannelData(0);\r\n        for (let i = 0; i < bufferSize; i++) {\r\n            output[i] = Math.random() * 2 - 1;\r\n        }\r\n    }\r\n\r\n    function makeDistortionCurve(amount) {\r\n        let k = amount, n = 44100, curve = new Float32Array(n), deg = Math.PI \/ 180;\r\n        for (let i = 0; i < n; ++i) {\r\n            let x = i * 2 \/ n - 1;\r\n            curve[i] = (3 + k) * x * 20 * deg \/ (Math.PI + k * Math.abs(x));\r\n        }\r\n        return curve;\r\n    }\r\n\r\n    function mtof(note) {\r\n        return baseFreq * Math.pow(2, note \/ 12);\r\n    }\r\n\r\n    function startSynth() {\r\n        initAudio();\r\n        if (audioCtx.state === 'suspended') audioCtx.resume();\r\n        if (mainOsc) return;\r\n\r\n        const preset = document.getElementById('preset').value;\r\n\r\n        mainOsc = audioCtx.createOscillator();\r\n        subOsc = audioCtx.createOscillator();\r\n\r\n        if (preset === 'saw') {\r\n            mainOsc.type = 'sawtooth'; subOsc.type = 'square';\r\n        } else if (preset === 'acid') {\r\n            mainOsc.type = 'sawtooth'; subOsc.type = 'sawtooth';\r\n        } else if (preset === 'sub') {\r\n            mainOsc.type = 'triangle'; subOsc.type = 'sine';\r\n        } else if (preset === 'noise') {\r\n            mainOsc.type = 'square'; subOsc.type = 'sawtooth';\r\n        }\r\n\r\n        mainOsc.connect(filterNode);\r\n        subOsc.connect(filterNode);\r\n\r\n        mainOsc.start();\r\n        subOsc.start();\r\n    }\r\n\r\n    function stopSynth() {\r\n        if (mainOsc) { mainOsc.stop(); mainOsc.disconnect(); mainOsc = null; }\r\n        if (subOsc) { subOsc.stop(); subOsc.disconnect(); subOsc = null; }\r\n    }\r\n\r\n    function updateSynth(x, y) {\r\n        if (!mainOsc) return;\r\n\r\n        const scaleType = document.getElementById('scale').value;\r\n        let freq;\r\n\r\n        if (scaleType === 'raw') {\r\n            freq = 80 * Math.pow(2, x * 4);\r\n        } else {\r\n            const currentScale = scales[scaleType];\r\n            const noteIndex = Math.floor(x * currentScale.length);\r\n            const note = currentScale[Math.min(noteIndex, currentScale.length - 1)];\r\n            freq = mtof(note);\r\n        }\r\n\r\n        const minVal = 100, maxVal = 10000;\r\n        const cutoff = minVal * Math.pow(maxVal \/ minVal, y);\r\n\r\n        \/\/ Immediate value scheduling for zero latency\r\n        const now = audioCtx.currentTime;\r\n        mainOsc.frequency.setValueAtTime(freq, now);\r\n        subOsc.frequency.setValueAtTime(freq \/ 2, now);\r\n        filterNode.frequency.setValueAtTime(cutoff, now);\r\n\r\n        if (document.getElementById('preset').value === 'acid') {\r\n            filterNode.Q.setValueAtTime(4 + (y * 18), now);\r\n        } else {\r\n            filterNode.Q.setValueAtTime(4, now);\r\n        }\r\n    }\r\n\r\n    \/\/ High-Precision Drum Synthesizer\r\n    function triggerDrum(type, time) {\r\n        if (type === 'kick') {\r\n            let osc = audioCtx.createOscillator();\r\n            let gain = audioCtx.createGain();\r\n            osc.frequency.setValueAtTime(180, time);\r\n            osc.frequency.exponentialRampToValueAtTime(30, time + 0.1);\r\n            gain.gain.setValueAtTime(1.4, time);\r\n            gain.gain.exponentialRampToValueAtTime(0.001, time + 0.14);\r\n            osc.connect(driveNode);\r\n            osc.start(time); osc.stop(time + 0.14);\r\n        } else if (type === 'snare') {\r\n            let noiseSrc = audioCtx.createBufferSource();\r\n            noiseSrc.buffer = noiseBuffer;\r\n            let filter = audioCtx.createBiquadFilter();\r\n            filter.type = 'highpass';\r\n            filter.frequency.value = 800;\r\n            let gain = audioCtx.createGain();\r\n            gain.gain.setValueAtTime(0.9, time);\r\n            gain.gain.exponentialRampToValueAtTime(0.01, time + 0.09);\r\n            noiseSrc.connect(filter);\r\n            filter.connect(driveNode);\r\n            noiseSrc.start(time); noiseSrc.stop(time + 0.09);\r\n        } else if (type === 'hat') {\r\n            let noiseSrc = audioCtx.createBufferSource();\r\n            noiseSrc.buffer = noiseBuffer;\r\n            let filter = audioCtx.createBiquadFilter();\r\n            filter.type = 'highpass';\r\n            filter.frequency.value = 6000;\r\n            let gain = audioCtx.createGain();\r\n            gain.gain.setValueAtTime(0.4, time);\r\n            gain.gain.exponentialRampToValueAtTime(0.001, time + 0.04);\r\n            noiseSrc.connect(filter);\r\n            filter.connect(driveNode);\r\n            noiseSrc.start(time); noiseSrc.stop(time + 0.04);\r\n        }\r\n    }\r\n\r\n    \/\/ Web Audio Lookahead Scheduler\r\n    function nextNote() {\r\n        const bpm = parseInt(document.getElementById('bpm').value);\r\n        const secondsPerBeat = 60.0 \/ bpm;\r\n        nextNoteTime += 0.25 * secondsPerBeat; \/\/ 16th note step\r\n        current16thNote = (current16thNote + 1) % 16;\r\n    }\r\n\r\n    function scheduleNote(step, time) {\r\n        const patKey = document.getElementById('beat-pattern').value;\r\n        const pat = drumPatterns[patKey];\r\n\r\n        if (pat.kick[step]) triggerDrum('kick', time);\r\n        if (pat.snare[step]) triggerDrum('snare', time);\r\n        if (pat.hat[step]) triggerDrum('hat', time);\r\n    }\r\n\r\n    function scheduler() {\r\n        while (nextNoteTime < audioCtx.currentTime + scheduleAheadTime) {\r\n            scheduleNote(current16thNote, nextNoteTime);\r\n            nextNote();\r\n        }\r\n        if (beatPlaying) {\r\n            timerID = window.setTimeout(scheduler, lookahead);\r\n        }\r\n    }\r\n\r\n    document.getElementById('beat-btn').addEventListener('click', (e) => {\r\n        initAudio();\r\n        if (audioCtx.state === 'suspended') audioCtx.resume();\r\n\r\n        beatPlaying = !beatPlaying;\r\n        e.target.classList.toggle('active', beatPlaying);\r\n\r\n        if (beatPlaying) {\r\n            current16thNote = 0;\r\n            nextNoteTime = audioCtx.currentTime;\r\n            scheduler();\r\n        } else {\r\n            clearTimeout(timerID);\r\n        }\r\n    });\r\n\r\n    \/\/ Touch \/ Mouse Interaction with RAF Decoupling for smooth performance\r\n    const pad = document.getElementById('pad');\r\n    const canvas = document.getElementById('visualizer');\r\n    const ctx = canvas.getContext('2d');\r\n    let touchX = 0, touchY = 0;\r\n\r\n    function resizeCanvas() {\r\n        canvas.width = pad.clientWidth; canvas.height = pad.clientHeight;\r\n    }\r\n    window.addEventListener('resize', resizeCanvas);\r\n    resizeCanvas();\r\n\r\n    function handleInputStart(e) {\r\n        isTouching = true;\r\n        startSynth();\r\n        handleInputMove(e);\r\n    }\r\n\r\n    function handleInputEnd() {\r\n        isTouching = false;\r\n        stopSynth();\r\n    }\r\n\r\n    function handleInputMove(e) {\r\n        if (!isTouching) return;\r\n        const rect = pad.getBoundingClientRect();\r\n        const clientX = e.touches ? e.touches[0].clientX : e.clientX;\r\n        const clientY = e.touches ? e.touches[0].clientY : e.clientY;\r\n\r\n        touchX = Math.max(0, Math.min(1, (clientX - rect.left) \/ rect.width));\r\n        touchY = Math.max(0, Math.min(1, 1 - (clientY - rect.top) \/ rect.height));\r\n\r\n        updateSynth(touchX, touchY);\r\n    }\r\n\r\n    pad.addEventListener('mousedown', handleInputStart);\r\n    window.addEventListener('mouseup', handleInputEnd);\r\n    pad.addEventListener('mousemove', handleInputMove);\r\n\r\n    pad.addEventListener('touchstart', handleInputStart, { passive: true });\r\n    window.addEventListener('touchend', handleInputEnd);\r\n    pad.addEventListener('touchmove', handleInputMove, { passive: true });\r\n\r\n    \/\/ Canvas Visualization Loop\r\n    function renderVisualizer() {\r\n        requestAnimationFrame(renderVisualizer);\r\n\r\n        ctx.fillStyle = 'rgba(5, 5, 5, 0.25)';\r\n        ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n\r\n        \/\/ Grid\r\n        ctx.strokeStyle = '#1a1a1a';\r\n        ctx.lineWidth = 1;\r\n        for (let i = 0; i < canvas.width; i += 30) {\r\n            ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, canvas.height); ctx.stroke();\r\n        }\r\n        for (let j = 0; j < canvas.height; j += 30) {\r\n            ctx.beginPath(); ctx.moveTo(0, j); ctx.lineTo(canvas.width, j); ctx.stroke();\r\n        }\r\n\r\n        \/\/ Touch Cursor\r\n        if (isTouching) {\r\n            const cx = touchX * canvas.width;\r\n            const cy = (1 - touchY) * canvas.height;\r\n\r\n            ctx.strokeStyle = 'rgba(255, 204, 0, 0.6)';\r\n            ctx.beginPath(); ctx.moveTo(cx, 0); ctx.lineTo(cx, canvas.height); ctx.stroke();\r\n            ctx.beginPath(); ctx.moveTo(0, cy); ctx.lineTo(canvas.width, cy); ctx.stroke();\r\n\r\n            ctx.fillStyle = '#ff3333';\r\n            ctx.shadowColor = '#ff3333';\r\n            ctx.shadowBlur = 15;\r\n            ctx.beginPath();\r\n            ctx.arc(cx, cy, 10, 0, Math.PI * 2);\r\n            ctx.fill();\r\n            ctx.shadowBlur = 0;\r\n        }\r\n    }\r\n    renderVisualizer();\r\n\r\n    \/\/ UI Display Listeners\r\n    document.getElementById('scale').addEventListener('change', (e) => {\r\n        document.getElementById('disp-scale').innerText = `SKALA: ${e.target.options[e.target.selectedIndex].text.toUpperCase()}`;\r\n    });\r\n\r\n    document.getElementById('preset').addEventListener('change', (e) => {\r\n        document.getElementById('disp-preset').innerText = `SYNTH: ${e.target.options[e.target.selectedIndex].text.toUpperCase()}`;\r\n        if (mainOsc) { stopSynth(); startSynth(); }\r\n    });\r\n\r\n    document.getElementById('beat-pattern').addEventListener('change', (e) => {\r\n        document.getElementById('disp-pattern').innerText = `BEAT: ${e.target.options[e.target.selectedIndex].text.toUpperCase()}`;\r\n    });\r\n\r\n    document.getElementById('bpm').addEventListener('change', (e) => {\r\n        document.getElementById('disp-bpm').innerText = `${e.target.value} BPM`;\r\n    });\r\n<\/script>\r\n\r\n<\/body>\r\n<\/html>\r\n"}