WME Map Comment Shapes

Erstelle Map Comments mit vordefinierten Formen (Kreis, Quadrat, etc.) im Waze Map Editor

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         WME Map Comment Shapes
// @namespace    https://greasyfork.org/de/users/863740-horst-wittlich
// @version      2026.01.01
// @author       Hiwi234
// @description  Erstelle Map Comments mit vordefinierten Formen (Kreis, Quadrat, etc.) im Waze Map Editor
// @include      https://www.waze.com/editor*
// @include      https://www.waze.com/*/editor*
// @include      https://beta.waze.com/*
// @exclude      https://www.waze.com/user/editor*
// @author       Custom
// @grant        none
// @license      MIT
// ==/UserScript==

/* global W, getWmeSdk */

(function () {
    'use strict';

    const SCRIPT_ID = 'wme-mapcomment-shapes';
    const SCRIPT_NAME = 'Map Comment Shapes';
    const SCRIPT_VERSION = '2025.01.02.17';

    const SHAPES = {
        POINT: 'point',
        CIRCLE: 'circle',
        SQUARE: 'square',
        RECTANGLE: 'rectangle',
        TRIANGLE: 'triangle',
        PENTAGON: 'pentagon',
        HEXAGON: 'hexagon',
        OCTAGON: 'octagon',
        STAR: 'star',
        ARROW_UP: 'arrow_up',
        ARROW_DOWN: 'arrow_down',
        ARROW_LEFT: 'arrow_left',
        ARROW_RIGHT: 'arrow_right',
        SPEECH_RECT: 'speech_rect',
        SPEECH_ROUND: 'speech_round',
        CUSTOM: 'custom'
    };

    // ============ I18N ============
    const I18N = {
        de: {
            // UI Labels
            selectShape: 'Form wählen:',
            arrows: 'Pfeile:',
            speechBubbles: 'Sprechblasen:',
            customShapes: 'Eigene Formen:',
            size: 'Größe:',
            dynamic: 'Dynamisch (2 Klicks)',
            radius: 'Radius:',
            commentContent: 'Kommentar-Inhalt:',
            titlePlaceholder: 'Titel (max 30 Zeichen)',
            descPlaceholder: 'Beschreibung (optional)',
            expiresIn: 'Ablauf in:',
            days: 'Tagen',
            templates: 'Vorlagen:',
            selectTemplate: '-- Vorlage wählen --',
            templateName: 'Vorlagenname',
            simplify: 'Simplify (Vereinfachen):',
            simplifyHint: 'Wähle einen Map Comment aus und klicke Simplify',
            tolerance: 'Toleranz:',
            highQuality: 'High Quality',
            instructions: 'Anleitung:',
            instrPoint: 'Punkt: 1 Klick = Position',
            instrDynamicOn: 'Dynamisch AN: 1. Klick = Mitte, 2. Klick = Radius',
            instrDynamicOff: 'Dynamisch AUS: 1 Klick = Mitte (fester Radius)',
            // Rotate
            rotate: 'Drehen:',
            rotateHint: 'Wähle einen Map Comment aus',
            angle: 'Winkel:',
            rotateBtn: 'Drehen',
            rotated: 'Gedreht um {angle}°',
            // Custom Shapes
            saveShape: 'Form speichern',
            shapeName: 'Formname',
            selectCustomShape: '-- Eigene Form wählen --',
            noCustomShapes: 'Keine eigenen Formen',
            shapeSaved: 'Form "{name}" gespeichert',
            shapeDeleted: 'Form "{name}" gelöscht',
            confirmDeleteShape: 'Form "{name}" wirklich löschen?',
            enterShapeName: 'Bitte Formname eingeben!',
            customShapeLoaded: 'Eigene Form geladen',
            // Shape titles
            shapePoint: 'Punkt',
            shapeCircle: 'Kreis',
            shapeSquare: 'Quadrat',
            shapeRectangle: 'Rechteck',
            shapeTriangle: 'Dreieck',
            shapePentagon: 'Fünfeck',
            shapeHexagon: 'Sechseck',
            shapeOctagon: 'Achteck',
            shapeStar: 'Stern',
            shapeArrowUp: 'Pfeil hoch',
            shapeArrowDown: 'Pfeil runter',
            shapeArrowLeft: 'Pfeil links',
            shapeArrowRight: 'Pfeil rechts',
            shapeSpeechRect: 'Sprechblase eckig',
            shapeSpeechRound: 'Sprechblase rund',
            shapeCustom: 'Eigene Form',
            // Status messages
            defaultStatus: 'Wähle eine Form und klicke auf die Karte',
            clickForCenter: 'Klicke für {shape}-Mittelpunkt',
            clickForPosition: 'Klicke für {shape}-Position',
            moveForSize: 'Bewege Maus für Größe, klicke zum Bestätigen',
            radiusDisplay: 'Radius: {radius}m - Klicke zum Bestätigen',
            commentCreated: 'Kommentar erstellt!',
            commentCreatedId: 'Kommentar erstellt! (ID: {id})',
            error: 'Fehler:',
            // Template messages
            enterTemplateName: 'Bitte Vorlagenname eingeben!',
            enterTitleOrDesc: 'Titel oder Beschreibung eingeben!',
            templateUpdated: 'Vorlage "{name}" aktualisiert',
            templateSaved: 'Vorlage "{name}" gespeichert',
            noTemplateSelected: 'Keine Vorlage ausgewählt!',
            templateLoaded: 'Vorlage "{name}" geladen',
            templateDeleted: 'Vorlage "{name}" gelöscht',
            confirmDelete: 'Vorlage "{name}" wirklich löschen?',
            // Simplify messages
            selectMapComment: 'Bitte Map Comment auswählen!',
            noValidPolygon: 'Kein gültiges Polygon!',
            tooFewPoints: 'Zu wenig Punkte nach Simplify!',
            simplified: 'Vereinfacht: {from} → {to} Punkte (Speichern!)',
            simplifyError: 'Fehler beim Vereinfachen:',
            preview: 'Vorschau: {from} → {to} Punkte',
            before: 'Vorher:',
            after: 'Nachher:',
            points: 'Punkte',
            reduction: 'Reduktion:',
            // Buttons
            cancel: 'Abbrechen',
            load: 'Laden',
            delete: 'Löschen',
            save: 'Speichern'
        },
        en: {
            selectShape: 'Select shape:',
            arrows: 'Arrows:',
            speechBubbles: 'Speech bubbles:',
            customShapes: 'Custom shapes:',
            size: 'Size:',
            dynamic: 'Dynamic (2 clicks)',
            radius: 'Radius:',
            commentContent: 'Comment content:',
            titlePlaceholder: 'Title (max 30 chars)',
            descPlaceholder: 'Description (optional)',
            expiresIn: 'Expires in:',
            days: 'days',
            templates: 'Templates:',
            selectTemplate: '-- Select template --',
            templateName: 'Template name',
            simplify: 'Simplify:',
            simplifyHint: 'Select a Map Comment and click Simplify',
            tolerance: 'Tolerance:',
            highQuality: 'High Quality',
            instructions: 'Instructions:',
            instrPoint: 'Point: 1 click = position',
            instrDynamicOn: 'Dynamic ON: 1st click = center, 2nd click = radius',
            instrDynamicOff: 'Dynamic OFF: 1 click = center (fixed radius)',
            // Rotate
            rotate: 'Rotate:',
            rotateHint: 'Select a Map Comment',
            angle: 'Angle:',
            rotateBtn: 'Rotate',
            rotated: 'Rotated by {angle}°',
            // Custom Shapes
            saveShape: 'Save shape',
            shapeName: 'Shape name',
            selectCustomShape: '-- Select custom shape --',
            noCustomShapes: 'No custom shapes',
            shapeSaved: 'Shape "{name}" saved',
            shapeDeleted: 'Shape "{name}" deleted',
            confirmDeleteShape: 'Really delete shape "{name}"?',
            enterShapeName: 'Please enter shape name!',
            customShapeLoaded: 'Custom shape loaded',
            shapePoint: 'Point',
            shapeCircle: 'Circle',
            shapeSquare: 'Square',
            shapeRectangle: 'Rectangle',
            shapeTriangle: 'Triangle',
            shapePentagon: 'Pentagon',
            shapeHexagon: 'Hexagon',
            shapeOctagon: 'Octagon',
            shapeStar: 'Star',
            shapeArrowUp: 'Arrow up',
            shapeArrowDown: 'Arrow down',
            shapeArrowLeft: 'Arrow left',
            shapeArrowRight: 'Arrow right',
            shapeSpeechRect: 'Speech bubble rect',
            shapeSpeechRound: 'Speech bubble round',
            shapeCustom: 'Custom shape',
            defaultStatus: 'Select a shape and click on the map',
            clickForCenter: 'Click for {shape} center',
            clickForPosition: 'Click for {shape} position',
            moveForSize: 'Move mouse for size, click to confirm',
            radiusDisplay: 'Radius: {radius}m - Click to confirm',
            commentCreated: 'Comment created!',
            commentCreatedId: 'Comment created! (ID: {id})',
            error: 'Error:',
            enterTemplateName: 'Please enter template name!',
            enterTitleOrDesc: 'Enter title or description!',
            templateUpdated: 'Template "{name}" updated',
            templateSaved: 'Template "{name}" saved',
            noTemplateSelected: 'No template selected!',
            templateLoaded: 'Template "{name}" loaded',
            templateDeleted: 'Template "{name}" deleted',
            confirmDelete: 'Really delete template "{name}"?',
            selectMapComment: 'Please select a Map Comment!',
            noValidPolygon: 'No valid polygon!',
            tooFewPoints: 'Too few points after simplify!',
            simplified: 'Simplified: {from} → {to} points (Save!)',
            simplifyError: 'Error simplifying:',
            preview: 'Preview: {from} → {to} points',
            before: 'Before:',
            after: 'After:',
            points: 'points',
            reduction: 'Reduction:',
            cancel: 'Cancel',
            load: 'Load',
            delete: 'Delete',
            save: 'Save'
        },
        it: {
            selectShape: 'Seleziona forma:',
            arrows: 'Frecce:',
            speechBubbles: 'Fumetti:',
            customShapes: 'Forme personalizzate:',
            size: 'Dimensione:',
            dynamic: 'Dinamico (2 clic)',
            radius: 'Raggio:',
            commentContent: 'Contenuto commento:',
            titlePlaceholder: 'Titolo (max 30 caratteri)',
            descPlaceholder: 'Descrizione (opzionale)',
            expiresIn: 'Scade tra:',
            days: 'giorni',
            templates: 'Modelli:',
            selectTemplate: '-- Seleziona modello --',
            templateName: 'Nome modello',
            simplify: 'Semplifica:',
            simplifyHint: 'Seleziona un Map Comment e clicca Semplifica',
            tolerance: 'Tolleranza:',
            highQuality: 'Alta qualità',
            instructions: 'Istruzioni:',
            instrPoint: 'Punto: 1 clic = posizione',
            instrDynamicOn: 'Dinamico ON: 1° clic = centro, 2° clic = raggio',
            instrDynamicOff: 'Dinamico OFF: 1 clic = centro (raggio fisso)',
            rotate: 'Ruota:',
            rotateHint: 'Seleziona un Map Comment',
            angle: 'Angolo:',
            rotateBtn: 'Ruota',
            rotated: 'Ruotato di {angle}°',
            saveShape: 'Salva forma',
            shapeName: 'Nome forma',
            selectCustomShape: '-- Seleziona forma --',
            noCustomShapes: 'Nessuna forma personalizzata',
            shapeSaved: 'Forma "{name}" salvata',
            shapeDeleted: 'Forma "{name}" eliminata',
            confirmDeleteShape: 'Eliminare davvero la forma "{name}"?',
            enterShapeName: 'Inserisci il nome della forma!',
            customShapeLoaded: 'Forma personalizzata caricata',
            shapePoint: 'Punto',
            shapeCircle: 'Cerchio',
            shapeSquare: 'Quadrato',
            shapeRectangle: 'Rettangolo',
            shapeTriangle: 'Triangolo',
            shapePentagon: 'Pentagono',
            shapeHexagon: 'Esagono',
            shapeOctagon: 'Ottagono',
            shapeStar: 'Stella',
            shapeArrowUp: 'Freccia su',
            shapeArrowDown: 'Freccia giù',
            shapeArrowLeft: 'Freccia sinistra',
            shapeArrowRight: 'Freccia destra',
            shapeSpeechRect: 'Fumetto rettangolare',
            shapeSpeechRound: 'Fumetto rotondo',
            shapeCustom: 'Forma personalizzata',
            defaultStatus: 'Seleziona una forma e clicca sulla mappa',
            clickForCenter: 'Clicca per il centro del {shape}',
            clickForPosition: 'Clicca per la posizione del {shape}',
            moveForSize: 'Muovi il mouse per la dimensione, clicca per confermare',
            radiusDisplay: 'Raggio: {radius}m - Clicca per confermare',
            commentCreated: 'Commento creato!',
            commentCreatedId: 'Commento creato! (ID: {id})',
            error: 'Errore:',
            enterTemplateName: 'Inserisci il nome del modello!',
            enterTitleOrDesc: 'Inserisci titolo o descrizione!',
            templateUpdated: 'Modello "{name}" aggiornato',
            templateSaved: 'Modello "{name}" salvato',
            noTemplateSelected: 'Nessun modello selezionato!',
            templateLoaded: 'Modello "{name}" caricato',
            templateDeleted: 'Modello "{name}" eliminato',
            confirmDelete: 'Eliminare davvero il modello "{name}"?',
            selectMapComment: 'Seleziona un Map Comment!',
            noValidPolygon: 'Nessun poligono valido!',
            tooFewPoints: 'Troppo pochi punti dopo la semplificazione!',
            simplified: 'Semplificato: {from} → {to} punti (Salva!)',
            simplifyError: 'Errore nella semplificazione:',
            preview: 'Anteprima: {from} → {to} punti',
            before: 'Prima:',
            after: 'Dopo:',
            points: 'punti',
            reduction: 'Riduzione:',
            cancel: 'Annulla',
            load: 'Carica',
            delete: 'Elimina',
            save: 'Salva'
        },
        es: {
            selectShape: 'Seleccionar forma:',
            arrows: 'Flechas:',
            speechBubbles: 'Bocadillos:',
            customShapes: 'Formas personalizadas:',
            size: 'Tamaño:',
            dynamic: 'Dinámico (2 clics)',
            radius: 'Radio:',
            commentContent: 'Contenido del comentario:',
            titlePlaceholder: 'Título (máx 30 caracteres)',
            descPlaceholder: 'Descripción (opcional)',
            expiresIn: 'Expira en:',
            days: 'días',
            templates: 'Plantillas:',
            selectTemplate: '-- Seleccionar plantilla --',
            templateName: 'Nombre de plantilla',
            simplify: 'Simplificar:',
            simplifyHint: 'Selecciona un Map Comment y haz clic en Simplificar',
            tolerance: 'Tolerancia:',
            highQuality: 'Alta calidad',
            instructions: 'Instrucciones:',
            instrPoint: 'Punto: 1 clic = posición',
            instrDynamicOn: 'Dinámico ON: 1er clic = centro, 2do clic = radio',
            instrDynamicOff: 'Dinámico OFF: 1 clic = centro (radio fijo)',
            rotate: 'Rotar:',
            rotateHint: 'Selecciona un Map Comment',
            angle: 'Ángulo:',
            rotateBtn: 'Rotar',
            rotated: 'Rotado {angle}°',
            saveShape: 'Guardar forma',
            shapeName: 'Nombre de forma',
            selectCustomShape: '-- Seleccionar forma --',
            noCustomShapes: 'Sin formas personalizadas',
            shapeSaved: 'Forma "{name}" guardada',
            shapeDeleted: 'Forma "{name}" eliminada',
            confirmDeleteShape: '¿Eliminar realmente la forma "{name}"?',
            enterShapeName: '¡Introduce el nombre de la forma!',
            customShapeLoaded: 'Forma personalizada cargada',
            shapePoint: 'Punto',
            shapeCircle: 'Círculo',
            shapeSquare: 'Cuadrado',
            shapeRectangle: 'Rectángulo',
            shapeTriangle: 'Triángulo',
            shapePentagon: 'Pentágono',
            shapeHexagon: 'Hexágono',
            shapeOctagon: 'Octágono',
            shapeStar: 'Estrella',
            shapeArrowUp: 'Flecha arriba',
            shapeArrowDown: 'Flecha abajo',
            shapeArrowLeft: 'Flecha izquierda',
            shapeArrowRight: 'Flecha derecha',
            shapeSpeechRect: 'Bocadillo rectangular',
            shapeSpeechRound: 'Bocadillo redondo',
            shapeCustom: 'Forma personalizada',
            defaultStatus: 'Selecciona una forma y haz clic en el mapa',
            clickForCenter: 'Clic para el centro del {shape}',
            clickForPosition: 'Clic para la posición del {shape}',
            moveForSize: 'Mueve el ratón para el tamaño, clic para confirmar',
            radiusDisplay: 'Radio: {radius}m - Clic para confirmar',
            commentCreated: '¡Comentario creado!',
            commentCreatedId: '¡Comentario creado! (ID: {id})',
            error: 'Error:',
            enterTemplateName: '¡Introduce el nombre de la plantilla!',
            enterTitleOrDesc: '¡Introduce título o descripción!',
            templateUpdated: 'Plantilla "{name}" actualizada',
            templateSaved: 'Plantilla "{name}" guardada',
            noTemplateSelected: '¡Ninguna plantilla seleccionada!',
            templateLoaded: 'Plantilla "{name}" cargada',
            templateDeleted: 'Plantilla "{name}" eliminada',
            confirmDelete: '¿Eliminar realmente la plantilla "{name}"?',
            selectMapComment: '¡Selecciona un Map Comment!',
            noValidPolygon: '¡No hay polígono válido!',
            tooFewPoints: '¡Muy pocos puntos después de simplificar!',
            simplified: 'Simplificado: {from} → {to} puntos (¡Guardar!)',
            simplifyError: 'Error al simplificar:',
            preview: 'Vista previa: {from} → {to} puntos',
            before: 'Antes:',
            after: 'Después:',
            points: 'puntos',
            reduction: 'Reducción:',
            cancel: 'Cancelar',
            load: 'Cargar',
            delete: 'Eliminar',
            save: 'Guardar'
        },
        fr: {
            selectShape: 'Choisir forme:',
            arrows: 'Flèches:',
            speechBubbles: 'Bulles:',
            customShapes: 'Formes personnalisées:',
            size: 'Taille:',
            dynamic: 'Dynamique (2 clics)',
            radius: 'Rayon:',
            commentContent: 'Contenu du commentaire:',
            titlePlaceholder: 'Titre (max 30 caractères)',
            descPlaceholder: 'Description (optionnel)',
            expiresIn: 'Expire dans:',
            days: 'jours',
            templates: 'Modèles:',
            selectTemplate: '-- Choisir modèle --',
            templateName: 'Nom du modèle',
            simplify: 'Simplifier:',
            simplifyHint: 'Sélectionnez un Map Comment et cliquez sur Simplifier',
            tolerance: 'Tolérance:',
            highQuality: 'Haute qualité',
            instructions: 'Instructions:',
            instrPoint: 'Point: 1 clic = position',
            instrDynamicOn: 'Dynamique ON: 1er clic = centre, 2e clic = rayon',
            instrDynamicOff: 'Dynamique OFF: 1 clic = centre (rayon fixe)',
            rotate: 'Rotation:',
            rotateHint: 'Sélectionnez un Map Comment',
            angle: 'Angle:',
            rotateBtn: 'Rotation',
            rotated: 'Pivoté de {angle}°',
            saveShape: 'Enregistrer forme',
            shapeName: 'Nom de forme',
            selectCustomShape: '-- Choisir forme --',
            noCustomShapes: 'Pas de formes personnalisées',
            shapeSaved: 'Forme "{name}" enregistrée',
            shapeDeleted: 'Forme "{name}" supprimée',
            confirmDeleteShape: 'Vraiment supprimer la forme "{name}"?',
            enterShapeName: 'Veuillez entrer le nom de la forme!',
            customShapeLoaded: 'Forme personnalisée chargée',
            shapePoint: 'Point',
            shapeCircle: 'Cercle',
            shapeSquare: 'Carré',
            shapeRectangle: 'Rectangle',
            shapeTriangle: 'Triangle',
            shapePentagon: 'Pentagone',
            shapeHexagon: 'Hexagone',
            shapeOctagon: 'Octogone',
            shapeStar: 'Étoile',
            shapeArrowUp: 'Flèche haut',
            shapeArrowDown: 'Flèche bas',
            shapeArrowLeft: 'Flèche gauche',
            shapeArrowRight: 'Flèche droite',
            shapeSpeechRect: 'Bulle rectangulaire',
            shapeSpeechRound: 'Bulle ronde',
            shapeCustom: 'Forme personnalisée',
            defaultStatus: 'Choisissez une forme et cliquez sur la carte',
            clickForCenter: 'Cliquez pour le centre du {shape}',
            clickForPosition: 'Cliquez pour la position du {shape}',
            moveForSize: 'Déplacez la souris pour la taille, cliquez pour confirmer',
            radiusDisplay: 'Rayon: {radius}m - Cliquez pour confirmer',
            commentCreated: 'Commentaire créé!',
            commentCreatedId: 'Commentaire créé! (ID: {id})',
            error: 'Erreur:',
            enterTemplateName: 'Veuillez entrer le nom du modèle!',
            enterTitleOrDesc: 'Entrez titre ou description!',
            templateUpdated: 'Modèle "{name}" mis à jour',
            templateSaved: 'Modèle "{name}" enregistré',
            noTemplateSelected: 'Aucun modèle sélectionné!',
            templateLoaded: 'Modèle "{name}" chargé',
            templateDeleted: 'Modèle "{name}" supprimé',
            confirmDelete: 'Vraiment supprimer le modèle "{name}"?',
            selectMapComment: 'Veuillez sélectionner un Map Comment!',
            noValidPolygon: 'Pas de polygone valide!',
            tooFewPoints: 'Trop peu de points après simplification!',
            simplified: 'Simplifié: {from} → {to} points (Enregistrer!)',
            simplifyError: 'Erreur lors de la simplification:',
            preview: 'Aperçu: {from} → {to} points',
            before: 'Avant:',
            after: 'Après:',
            points: 'points',
            reduction: 'Réduction:',
            cancel: 'Annuler',
            load: 'Charger',
            delete: 'Supprimer',
            save: 'Enregistrer'
        },
        nl: {
            selectShape: 'Kies vorm:',
            arrows: 'Pijlen:',
            speechBubbles: 'Tekstballonnen:',
            customShapes: 'Aangepaste vormen:',
            size: 'Grootte:',
            dynamic: 'Dynamisch (2 klikken)',
            radius: 'Straal:',
            commentContent: 'Commentaar inhoud:',
            titlePlaceholder: 'Titel (max 30 tekens)',
            descPlaceholder: 'Beschrijving (optioneel)',
            expiresIn: 'Verloopt over:',
            days: 'dagen',
            templates: 'Sjablonen:',
            selectTemplate: '-- Kies sjabloon --',
            templateName: 'Sjabloonnaam',
            simplify: 'Vereenvoudigen:',
            simplifyHint: 'Selecteer een Map Comment en klik op Vereenvoudigen',
            tolerance: 'Tolerantie:',
            highQuality: 'Hoge kwaliteit',
            instructions: 'Instructies:',
            instrPoint: 'Punt: 1 klik = positie',
            instrDynamicOn: 'Dynamisch AAN: 1e klik = midden, 2e klik = straal',
            instrDynamicOff: 'Dynamisch UIT: 1 klik = midden (vaste straal)',
            rotate: 'Draaien:',
            rotateHint: 'Selecteer een Map Comment',
            angle: 'Hoek:',
            rotateBtn: 'Draaien',
            rotated: 'Gedraaid met {angle}°',
            saveShape: 'Vorm opslaan',
            shapeName: 'Vormnaam',
            selectCustomShape: '-- Kies vorm --',
            noCustomShapes: 'Geen aangepaste vormen',
            shapeSaved: 'Vorm "{name}" opgeslagen',
            shapeDeleted: 'Vorm "{name}" verwijderd',
            confirmDeleteShape: 'Vorm "{name}" echt verwijderen?',
            enterShapeName: 'Voer vormnaam in!',
            customShapeLoaded: 'Aangepaste vorm geladen',
            shapePoint: 'Punt',
            shapeCircle: 'Cirkel',
            shapeSquare: 'Vierkant',
            shapeRectangle: 'Rechthoek',
            shapeTriangle: 'Driehoek',
            shapePentagon: 'Vijfhoek',
            shapeHexagon: 'Zeshoek',
            shapeOctagon: 'Achthoek',
            shapeStar: 'Ster',
            shapeArrowUp: 'Pijl omhoog',
            shapeArrowDown: 'Pijl omlaag',
            shapeArrowLeft: 'Pijl links',
            shapeArrowRight: 'Pijl rechts',
            shapeSpeechRect: 'Tekstballon rechthoekig',
            shapeSpeechRound: 'Tekstballon rond',
            shapeCustom: 'Aangepaste vorm',
            defaultStatus: 'Kies een vorm en klik op de kaart',
            clickForCenter: 'Klik voor {shape} middelpunt',
            clickForPosition: 'Klik voor {shape} positie',
            moveForSize: 'Beweeg muis voor grootte, klik om te bevestigen',
            radiusDisplay: 'Straal: {radius}m - Klik om te bevestigen',
            commentCreated: 'Commentaar aangemaakt!',
            commentCreatedId: 'Commentaar aangemaakt! (ID: {id})',
            error: 'Fout:',
            enterTemplateName: 'Voer sjabloonnaam in!',
            enterTitleOrDesc: 'Voer titel of beschrijving in!',
            templateUpdated: 'Sjabloon "{name}" bijgewerkt',
            templateSaved: 'Sjabloon "{name}" opgeslagen',
            noTemplateSelected: 'Geen sjabloon geselecteerd!',
            templateLoaded: 'Sjabloon "{name}" geladen',
            templateDeleted: 'Sjabloon "{name}" verwijderd',
            confirmDelete: 'Sjabloon "{name}" echt verwijderen?',
            selectMapComment: 'Selecteer een Map Comment!',
            noValidPolygon: 'Geen geldig polygoon!',
            tooFewPoints: 'Te weinig punten na vereenvoudigen!',
            simplified: 'Vereenvoudigd: {from} → {to} punten (Opslaan!)',
            simplifyError: 'Fout bij vereenvoudigen:',
            preview: 'Voorbeeld: {from} → {to} punten',
            before: 'Voor:',
            after: 'Na:',
            points: 'punten',
            reduction: 'Reductie:',
            cancel: 'Annuleren',
            load: 'Laden',
            delete: 'Verwijderen',
            save: 'Opslaan'
        }
    };

    let currentLang = 'en';

    function detectLanguage() {
        try {
            // WME Sprache aus I18n
            if (window.I18n?.currentLocale) {
                const locale = window.I18n.currentLocale();
                const lang = locale.split('-')[0].toLowerCase();
                if (I18N[lang]) return lang;
            }
            // Fallback: Browser-Sprache
            const browserLang = navigator.language?.split('-')[0].toLowerCase();
            if (I18N[browserLang]) return browserLang;
        } catch (e) {}
        return 'en';
    }

    function t(key, params = {}) {
        let text = I18N[currentLang]?.[key] || I18N.en[key] || key;
        for (const [k, v] of Object.entries(params)) {
            text = text.replace(`{${k}}`, v);
        }
        return text;
    }

    function getShapeName(shape) {
        const shapeNames = {
            [SHAPES.POINT]: t('shapePoint'),
            [SHAPES.CIRCLE]: t('shapeCircle'),
            [SHAPES.SQUARE]: t('shapeSquare'),
            [SHAPES.RECTANGLE]: t('shapeRectangle'),
            [SHAPES.TRIANGLE]: t('shapeTriangle'),
            [SHAPES.PENTAGON]: t('shapePentagon'),
            [SHAPES.HEXAGON]: t('shapeHexagon'),
            [SHAPES.OCTAGON]: t('shapeOctagon'),
            [SHAPES.STAR]: t('shapeStar'),
            [SHAPES.ARROW_UP]: t('shapeArrowUp'),
            [SHAPES.ARROW_DOWN]: t('shapeArrowDown'),
            [SHAPES.ARROW_LEFT]: t('shapeArrowLeft'),
            [SHAPES.ARROW_RIGHT]: t('shapeArrowRight'),
            [SHAPES.SPEECH_RECT]: t('shapeSpeechRect'),
            [SHAPES.SPEECH_ROUND]: t('shapeSpeechRound')
        };
        return shapeNames[shape] || shape;
    }

    const EARTH_RADIUS = 6371000;
    const PREVIEW_LAYER = '__MCS_Preview';

    let sdk = null;
    let _settings;
    let isDrawing = false;
    let drawingMode = null;
    let drawPoints = [];
    let shapeCenter = null;
    let previewLayerCreated = false;
    let customShapeCoords = null; // Für eigene Form beim Zeichnen

    const defaultSettings = {
        defaultRadius: 50,
        defaultSubject: '',
        defaultBody: '',
        expirationDays: 30,
        dynamicSize: true,
        templates: [], // Gespeicherte Vorlagen: [{name, subject, body}]
        customShapes: [] // Eigene Formen: [{name, coords}] - coords sind normalisiert (-1 bis 1)
    };

    // ============ GEO MATH ============

    function toRadians(deg) { return deg * Math.PI / 180; }
    function toDegrees(rad) { return rad * 180 / Math.PI; }

    // Berechne Distanz zwischen zwei Punkten in Metern (Haversine)
    function distanceBetween(coord1, coord2) {
        const lon1 = toRadians(coord1[0]);
        const lat1 = toRadians(coord1[1]);
        const lon2 = toRadians(coord2[0]);
        const lat2 = toRadians(coord2[1]);

        const dLat = lat2 - lat1;
        const dLon = lon2 - lon1;

        const a = Math.sin(dLat / 2) ** 2 +
                  Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return EARTH_RADIUS * c;
    }

    // ============ SIMPLIFY (Douglas-Peucker + Radial Distance) ============
    // Basiert auf simplify-js von Vladimir Agafonkin (mourner)
    // Angepasst für Geo-Koordinaten mit Meter-Toleranz

    // Quadratische Distanz in Metern zwischen zwei Geo-Punkten
    function getSqDistMeters(p1, p2) {
        const avgLat = (p1[1] + p2[1]) / 2;
        const latScale = 111000; // Meter pro Grad Latitude
        const lonScale = 111000 * Math.cos(avgLat * Math.PI / 180);

        const dx = (p2[0] - p1[0]) * lonScale;
        const dy = (p2[1] - p1[1]) * latScale;

        return dx * dx + dy * dy;
    }

    // Quadratische Distanz in Metern von Punkt zu Liniensegment
    function getSqSegDistMeters(p, p1, p2) {
        const avgLat = (p1[1] + p2[1] + p[1]) / 3;
        const latScale = 111000;
        const lonScale = 111000 * Math.cos(avgLat * Math.PI / 180);

        const px = p[0] * lonScale, py = p[1] * latScale;
        const p1x = p1[0] * lonScale, p1y = p1[1] * latScale;
        const p2x = p2[0] * lonScale, p2y = p2[1] * latScale;

        let x = p1x, y = p1y;
        let dx = p2x - x, dy = p2y - y;

        if (dx !== 0 || dy !== 0) {
            const t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy);
            if (t > 1) {
                x = p2x;
                y = p2y;
            } else if (t > 0) {
                x += dx * t;
                y += dy * t;
            }
        }

        dx = px - x;
        dy = py - y;
        return dx * dx + dy * dy;
    }

    // Radial Distance Simplification
    function simplifyRadialDist(points, sqToleranceMeters) {
        let prevPoint = points[0];
        const newPoints = [prevPoint];

        for (let i = 1, len = points.length; i < len; i++) {
            const point = points[i];
            if (getSqDistMeters(point, prevPoint) > sqToleranceMeters) {
                newPoints.push(point);
                prevPoint = point;
            }
        }

        if (prevPoint !== points[points.length - 1]) {
            newPoints.push(points[points.length - 1]);
        }

        return newPoints;
    }

    // Douglas-Peucker Simplification (rekursiv)
    function simplifyDPStep(points, first, last, sqToleranceMeters, simplified) {
        let maxSqDist = sqToleranceMeters;
        let index = 0;

        for (let i = first + 1; i < last; i++) {
            const sqDist = getSqSegDistMeters(points[i], points[first], points[last]);
            if (sqDist > maxSqDist) {
                index = i;
                maxSqDist = sqDist;
            }
        }

        if (maxSqDist > sqToleranceMeters) {
            if (index - first > 1) simplifyDPStep(points, first, index, sqToleranceMeters, simplified);
            simplified.push(points[index]);
            if (last - index > 1) simplifyDPStep(points, index, last, sqToleranceMeters, simplified);
        }
    }

    function simplifyDouglasPeucker(points, sqToleranceMeters) {
        const last = points.length - 1;
        const simplified = [points[0]];
        simplifyDPStep(points, 0, last, sqToleranceMeters, simplified);
        simplified.push(points[last]);
        return simplified;
    }

    // Hauptfunktion: Simplify (Toleranz in Metern)
    function simplify(points, toleranceMeters, highQuality) {
        if (points.length <= 2) return points;

        const sqToleranceMeters = toleranceMeters * toleranceMeters;

        let result = highQuality ? points : simplifyRadialDist(points, sqToleranceMeters);
        result = simplifyDouglasPeucker(result, sqToleranceMeters);

        return result;
    }

    function destinationPoint(start, distanceMeters, bearingDegrees) {
        // Sicherstellen dass alle Werte Numbers sind
        const startLon = Number(start[0]);
        const startLat = Number(start[1]);
        const dist = Number(distanceMeters);
        const bearing = Number(bearingDegrees);

        const lon1 = toRadians(startLon);
        const lat1 = toRadians(startLat);
        const bearingRad = toRadians(bearing);
        const angularDist = dist / EARTH_RADIUS;

        const lat2 = Math.asin(
            Math.sin(lat1) * Math.cos(angularDist) +
            Math.cos(lat1) * Math.sin(angularDist) * Math.cos(bearingRad)
        );
        const lon2 = lon1 + Math.atan2(
            Math.sin(bearingRad) * Math.sin(angularDist) * Math.cos(lat1),
            Math.cos(angularDist) - Math.sin(lat1) * Math.sin(lat2)
        );
        return [toDegrees(lon2), toDegrees(lat2)];
    }

    function createCircleCoords(center, radius, steps = 32) {
        const coords = [];
        for (let i = 0; i <= steps; i++) {
            coords.push(destinationPoint(center, radius, (i / steps) * 360));
        }
        return coords;
    }

    function createRegularPolygonCoords(center, radius, sides, rotationOffset = 0) {
        const coords = [];
        for (let i = 0; i <= sides; i++) {
            const angle = (i * 360 / sides) + rotationOffset - 90;
            coords.push(destinationPoint(center, radius, angle));
        }
        return coords;
    }

    // Rechteck: Breite = 1.5x Höhe
    function createRectangleCoords(center, radius) {
        const width = radius * 1.5;
        const height = radius;
        const coords = [
            destinationPoint(destinationPoint(center, height, 0), width, 90),    // Oben rechts
            destinationPoint(destinationPoint(center, height, 180), width, 90),  // Unten rechts
            destinationPoint(destinationPoint(center, height, 180), width, 270), // Unten links
            destinationPoint(destinationPoint(center, height, 0), width, 270),   // Oben links
            destinationPoint(destinationPoint(center, height, 0), width, 90)     // Zurück zum Start
        ];
        return coords;
    }

    function createStarCoords(center, outerRadius, points = 5) {
        const innerRadius = outerRadius * 0.4;
        const coords = [];
        const total = points * 2;
        for (let i = 0; i <= total; i++) {
            const angle = (i * 360 / total) - 90;
            const r = i % 2 === 0 ? outerRadius : innerRadius;
            coords.push(destinationPoint(center, r, angle));
        }
        return coords;
    }

    // Pfeil-Form erstellen (Richtung: 0=hoch, 90=rechts, 180=runter, 270=links)
    function createArrowCoords(center, size, direction = 0) {
        // Pfeil-Punkte relativ (normalisiert auf 1)
        // Spitze oben, Basis unten
        const arrowPoints = [
            [0, 1],      // Spitze
            [0.4, 0.3],  // Rechte Schulter
            [0.2, 0.3],  // Rechter Schaft oben
            [0.2, -1],   // Rechter Schaft unten
            [-0.2, -1],  // Linker Schaft unten
            [-0.2, 0.3], // Linker Schaft oben
            [-0.4, 0.3], // Linke Schulter
            [0, 1]       // Zurück zur Spitze
        ];

        const coords = [];
        for (const [x, y] of arrowPoints) {
            // Rotieren
            const rad = toRadians(direction);
            const rx = x * Math.cos(rad) - y * Math.sin(rad);
            const ry = x * Math.sin(rad) + y * Math.cos(rad);

            // Bearing und Distanz berechnen
            const bearing = toDegrees(Math.atan2(rx, ry));
            const dist = Math.sqrt(rx * rx + ry * ry) * size;

            coords.push(destinationPoint(center, dist, bearing));
        }
        return coords;
    }

    // Eckige Sprechblase (Rechteck mit Spitze unten links)
    function createSpeechRectCoords(center, size) {
        const points = [
            [-1, 0.6],    // Oben links
            [1, 0.6],     // Oben rechts
            [1, -0.3],    // Unten rechts
            [-0.3, -0.3], // Vor der Spitze
            [-0.6, -1],   // Spitze
            [-0.6, -0.3], // Nach der Spitze
            [-1, -0.3],   // Unten links
            [-1, 0.6]     // Zurück
        ];

        const coords = [];
        for (const [x, y] of points) {
            const bearing = toDegrees(Math.atan2(x, y));
            const dist = Math.sqrt(x * x + y * y) * size;
            coords.push(destinationPoint(center, dist, bearing));
        }
        return coords;
    }

    // Runde Sprechblase (Ellipse mit Spitze unten links)
    function createSpeechRoundCoords(center, size) {
        const coords = [];
        const steps = 24;

        // Ellipse zeichnen (etwas breiter als hoch)
        for (let i = 0; i <= steps; i++) {
            const angle = (i / steps) * 360;
            const rad = toRadians(angle);

            // Ellipse: breiter (1.2) als hoch (0.8), nach oben verschoben
            const x = Math.sin(rad) * 1.0;
            const y = Math.cos(rad) * 0.7 + 0.2; // Nach oben verschieben

            const bearing = toDegrees(Math.atan2(x, y));
            const dist = Math.sqrt(x * x + y * y) * size;
            coords.push(destinationPoint(center, dist, bearing));
        }

        // Spitze einfügen (bei ca. 210° = unten links)
        const tipIndex = Math.floor(steps * 0.6); // Position für Spitze
        const tipPoint = destinationPoint(center, size * 1.3, 210); // Spitze nach unten-links

        // Spitze in die Koordinaten einfügen
        coords.splice(tipIndex, 0, tipPoint);

        return coords;
    }

    // ============ INIT ============

    function init() {
        if (typeof W === 'undefined' || !W.userscripts) {
            setTimeout(init, 500);
            return;
        }

        if (W.userscripts.state?.isReady) {
            onWmeReady();
        } else {
            document.addEventListener('wme-ready', onWmeReady, { once: true });
        }
    }

    function onWmeReady() {
        console.log(`${SCRIPT_NAME} v${SCRIPT_VERSION} - Initializing`);

        // Sprache erkennen
        currentLang = detectLanguage();
        console.log(`${SCRIPT_NAME} - Language: ${currentLang}`);

        // SDK initialisieren
        if (typeof getWmeSdk === 'function') {
            sdk = getWmeSdk({ scriptId: SCRIPT_ID, scriptName: SCRIPT_NAME });
        }

        if (!sdk) {
            console.error(`${SCRIPT_NAME} - SDK not available!`);
            return;
        }

        loadSettings();
        injectStyles();
        createPreviewLayer();
        createSidebarTab();
    }

    function createPreviewLayer() {
        if (previewLayerCreated) return;

        try {
            sdk.Map.addLayer({
                layerName: PREVIEW_LAYER,
                styleRules: [{
                    predicate: () => true,
                    style: {
                        fillColor: '#4a90d9',
                        fillOpacity: 0.3,
                        strokeColor: '#357abd',
                        strokeWidth: 2,
                        strokeDashstyle: 'dash'
                    }
                }]
            });
            sdk.Map.setLayerVisibility({ layerName: PREVIEW_LAYER, visibility: true });
            previewLayerCreated = true;
            console.log(`${SCRIPT_NAME} - Preview layer created`);
        } catch (e) {
            console.warn(`${SCRIPT_NAME} - Could not create preview layer:`, e);
        }
    }

    function updatePreview(coords) {
        if (!previewLayerCreated || !coords || coords.length < 3) {
            clearPreview();
            return;
        }

        try {
            sdk.Map.removeAllFeaturesFromLayer({ layerName: PREVIEW_LAYER });

            const feature = {
                type: 'Feature',
                id: 'preview',
                geometry: {
                    type: 'Polygon',
                    coordinates: [coords]
                },
                properties: {}
            };

            sdk.Map.addFeaturesToLayer({
                layerName: PREVIEW_LAYER,
                features: [feature]
            });
        } catch (e) {
            // Ignore preview errors
        }
    }

    function clearPreview() {
        if (!previewLayerCreated) return;
        try {
            sdk.Map.removeAllFeaturesFromLayer({ layerName: PREVIEW_LAYER });
        } catch (e) {
            // Ignore
        }
    }

    function loadSettings() {
        try {
            const saved = localStorage.getItem('WME_MapCommentShapes');
            _settings = saved ? { ...defaultSettings, ...JSON.parse(saved) } : { ...defaultSettings };
        } catch (e) {
            _settings = { ...defaultSettings };
        }
    }

    function saveSettings() {
        try {
            _settings.defaultRadius = parseInt(document.getElementById('mcs-radius')?.value) || 50;
            _settings.defaultSubject = document.getElementById('mcs-subject')?.value || '';
            _settings.defaultBody = document.getElementById('mcs-body')?.value || '';
            _settings.expirationDays = parseInt(document.getElementById('mcs-expiration')?.value) || 30;
            _settings.dynamicSize = document.getElementById('mcs-dynamic')?.checked ?? true;
            localStorage.setItem('WME_MapCommentShapes', JSON.stringify(_settings));
        } catch (e) {
            console.error('Error saving settings:', e);
        }
    }

    // ============ SIDEBAR TAB ============

    function createSidebarTab() {
        try {
            const { tabLabel, tabPane } = W.userscripts.registerSidebarTab(SCRIPT_ID);

            tabLabel.innerText = '📝';
            tabLabel.title = SCRIPT_NAME;

            W.userscripts.waitForElementConnected(tabPane).then(() => {
                tabPane.innerHTML = buildTabContent();
                bindEvents();
                applySettings();
                console.log(`${SCRIPT_NAME} - Tab created`);
            });
        } catch (e) {
            console.error(`${SCRIPT_NAME} - Error creating tab:`, e);
        }
    }

    function buildTabContent() {
        return `
            <div class="mcs-container">
                <h4>📝 Map Comment Shapes</h4>
                <p class="mcs-version">v${SCRIPT_VERSION}</p>

                <div class="mcs-section">
                    <label class="mcs-label">${t('selectShape')}</label>
                    <div class="mcs-shape-grid">
                        <button class="mcs-btn" data-shape="${SHAPES.POINT}" title="${t('shapePoint')}">📍</button>
                        <button class="mcs-btn" data-shape="${SHAPES.CIRCLE}" title="${t('shapeCircle')}">⭕</button>
                        <button class="mcs-btn" data-shape="${SHAPES.SQUARE}" title="${t('shapeSquare')}">⬜</button>
                        <button class="mcs-btn" data-shape="${SHAPES.RECTANGLE}" title="${t('shapeRectangle')}">▭</button>
                        <button class="mcs-btn" data-shape="${SHAPES.TRIANGLE}" title="${t('shapeTriangle')}">△</button>
                        <button class="mcs-btn" data-shape="${SHAPES.PENTAGON}" title="${t('shapePentagon')}">⬠</button>
                        <button class="mcs-btn" data-shape="${SHAPES.HEXAGON}" title="${t('shapeHexagon')}">⬡</button>
                        <button class="mcs-btn" data-shape="${SHAPES.OCTAGON}" title="${t('shapeOctagon')}">🛑</button>
                        <button class="mcs-btn" data-shape="${SHAPES.STAR}" title="${t('shapeStar')}">⭐</button>
                    </div>
                    <label class="mcs-label mcs-sublabel">${t('arrows')}</label>
                    <div class="mcs-shape-grid mcs-arrows">
                        <button class="mcs-btn" data-shape="${SHAPES.ARROW_UP}" title="${t('shapeArrowUp')}">⬆️</button>
                        <button class="mcs-btn" data-shape="${SHAPES.ARROW_DOWN}" title="${t('shapeArrowDown')}">⬇️</button>
                        <button class="mcs-btn" data-shape="${SHAPES.ARROW_LEFT}" title="${t('shapeArrowLeft')}">⬅️</button>
                        <button class="mcs-btn" data-shape="${SHAPES.ARROW_RIGHT}" title="${t('shapeArrowRight')}">➡️</button>
                    </div>
                    <label class="mcs-label mcs-sublabel">${t('speechBubbles')}</label>
                    <div class="mcs-shape-grid mcs-speech">
                        <button class="mcs-btn" data-shape="${SHAPES.SPEECH_RECT}" title="${t('shapeSpeechRect')}">💬</button>
                        <button class="mcs-btn" data-shape="${SHAPES.SPEECH_ROUND}" title="${t('shapeSpeechRound')}">🗨️</button>
                    </div>
                </div>

                <div class="mcs-section">
                    <label class="mcs-label">${t('size')}</label>
                    <div class="mcs-row">
                        <label class="mcs-checkbox">
                            <input type="checkbox" id="mcs-dynamic" checked>
                            ${t('dynamic')}
                        </label>
                    </div>
                    <div class="mcs-row" id="mcs-radius-row">
                        <span>${t('radius')}</span>
                        <input type="number" id="mcs-radius" min="5" max="1000" value="50"> m
                    </div>
                </div>

                <div class="mcs-section">
                    <label class="mcs-label">${t('commentContent')}</label>
                    <div class="mcs-row-full">
                        <input type="text" id="mcs-subject" maxlength="30" placeholder="${t('titlePlaceholder')}">
                    </div>
                    <div class="mcs-row-full">
                        <textarea id="mcs-body" rows="3" maxlength="2000" placeholder="${t('descPlaceholder')}"></textarea>
                    </div>
                    <div class="mcs-row">
                        <span>${t('expiresIn')}</span>
                        <input type="number" id="mcs-expiration" min="1" max="365" value="30"> ${t('days')}
                    </div>
                </div>

                <div class="mcs-section">
                    <label class="mcs-label">📋 ${t('templates')}</label>
                    <div class="mcs-row">
                        <select id="mcs-template-select" class="mcs-select">
                            <option value="">${t('selectTemplate')}</option>
                        </select>
                        <button id="mcs-template-load" class="mcs-small-btn" title="${t('load')}">📥</button>
                        <button id="mcs-template-delete" class="mcs-small-btn mcs-delete" title="${t('delete')}">🗑️</button>
                    </div>
                    <div class="mcs-row">
                        <input type="text" id="mcs-template-name" placeholder="${t('templateName')}" class="mcs-template-input">
                        <button id="mcs-template-save" class="mcs-small-btn mcs-save" title="${t('save')}">💾</button>
                    </div>
                </div>

                <div class="mcs-section">
                    <div id="mcs-status" class="mcs-status">${t('defaultStatus')}</div>
                    <div class="mcs-actions">
                        <button id="mcs-cancel" class="mcs-action-btn mcs-cancel" style="display:none;">${t('cancel')}</button>
                    </div>
                </div>

                <div class="mcs-section mcs-simplify-section">
                    <label class="mcs-label">✂️ ${t('simplify')}</label>
                    <p class="mcs-hint">${t('simplifyHint')}</p>
                    <div class="mcs-row">
                        <span>${t('tolerance')}</span>
                        <input type="range" id="mcs-simplify-tolerance" min="1" max="50" value="5" class="mcs-slider">
                        <span id="mcs-tolerance-value">5m</span>
                    </div>
                    <div class="mcs-row">
                        <label class="mcs-checkbox">
                            <input type="checkbox" id="mcs-simplify-hq" checked>
                            ${t('highQuality')}
                        </label>
                    </div>
                    <div class="mcs-row mcs-simplify-actions">
                        <button id="mcs-simplify-btn" class="mcs-action-btn mcs-simplify">✂️ Simplify</button>
                        <button id="mcs-simplify-preview" class="mcs-small-btn" title="${t('preview')}">👁️</button>
                    </div>
                    <div id="mcs-simplify-info" class="mcs-simplify-info"></div>
                </div>

                <div class="mcs-section mcs-rotate-section">
                    <label class="mcs-label">🔄 ${t('rotate')}</label>
                    <p class="mcs-hint">${t('rotateHint')}</p>
                    <div class="mcs-row">
                        <span>${t('angle')}</span>
                        <input type="range" id="mcs-rotate-angle" min="-180" max="180" value="45" class="mcs-slider">
                        <span id="mcs-angle-value">45°</span>
                    </div>
                    <div class="mcs-row mcs-rotate-actions">
                        <button id="mcs-rotate-btn" class="mcs-action-btn mcs-rotate">🔄 ${t('rotateBtn')}</button>
                    </div>
                </div>

                <div class="mcs-section mcs-custom-section">
                    <label class="mcs-label">🎨 ${t('customShapes')}</label>
                    <div class="mcs-row">
                        <select id="mcs-custom-select" class="mcs-select">
                            <option value="">${t('selectCustomShape')}</option>
                        </select>
                        <button id="mcs-custom-use" class="mcs-small-btn" title="${t('load')}">▶️</button>
                        <button id="mcs-custom-delete" class="mcs-small-btn mcs-delete" title="${t('delete')}">🗑️</button>
                    </div>
                    <div class="mcs-row">
                        <input type="text" id="mcs-custom-name" placeholder="${t('shapeName')}" class="mcs-template-input">
                        <button id="mcs-custom-save" class="mcs-small-btn mcs-save" title="${t('saveShape')}">💾</button>
                    </div>
                    <p class="mcs-hint-small">💡 ${t('simplifyHint').replace('Simplify', t('saveShape'))}</p>
                </div>

                <div class="mcs-section mcs-help">
                    <label class="mcs-label">${t('instructions')}</label>
                    <ul>
                        <li>${t('instrPoint')}</li>
                        <li>${t('instrDynamicOn')}</li>
                        <li>${t('instrDynamicOff')}</li>
                    </ul>
                </div>
            </div>
        `;
    }

    function bindEvents() {
        document.querySelectorAll('.mcs-btn[data-shape]').forEach(btn => {
            btn.addEventListener('click', (e) => {
                e.preventDefault();
                const shape = btn.dataset.shape;
                startDrawing(shape);
                document.querySelectorAll('.mcs-btn').forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
            });
        });

        document.getElementById('mcs-cancel')?.addEventListener('click', cancelDrawing);

        // Dynamic checkbox toggle
        document.getElementById('mcs-dynamic')?.addEventListener('change', (e) => {
            const radiusRow = document.getElementById('mcs-radius-row');
            if (radiusRow) {
                radiusRow.style.display = e.target.checked ? 'none' : 'flex';
            }
            saveSettings();
        });

        // Template buttons
        document.getElementById('mcs-template-save')?.addEventListener('click', saveTemplate);
        document.getElementById('mcs-template-load')?.addEventListener('click', loadTemplate);
        document.getElementById('mcs-template-delete')?.addEventListener('click', deleteTemplate);

        // Simplify buttons
        document.getElementById('mcs-simplify-btn')?.addEventListener('click', simplifySelectedComment);
        document.getElementById('mcs-simplify-preview')?.addEventListener('click', previewSimplify);
        document.getElementById('mcs-simplify-tolerance')?.addEventListener('input', (e) => {
            document.getElementById('mcs-tolerance-value').textContent = e.target.value + 'm';
        });

        // Rotate buttons
        document.getElementById('mcs-rotate-btn')?.addEventListener('click', rotateSelectedComment);
        document.getElementById('mcs-rotate-angle')?.addEventListener('input', (e) => {
            document.getElementById('mcs-angle-value').textContent = e.target.value + '°';
            // Echtzeit-Vorschau beim Slider-Bewegen
            previewRotate();
        });
        // Vorschau löschen wenn Slider losgelassen wird
        document.getElementById('mcs-rotate-angle')?.addEventListener('change', () => {
            clearPreview();
        });

        // Custom shapes buttons
        document.getElementById('mcs-custom-save')?.addEventListener('click', saveCustomShape);
        document.getElementById('mcs-custom-use')?.addEventListener('click', useCustomShape);
        document.getElementById('mcs-custom-delete')?.addEventListener('click', deleteCustomShape);

        ['mcs-radius', 'mcs-subject', 'mcs-body', 'mcs-expiration'].forEach(id => {
            document.getElementById(id)?.addEventListener('change', saveSettings);
        });
    }

    function applySettings() {
        const el = (id) => document.getElementById(id);
        if (el('mcs-radius')) el('mcs-radius').value = _settings.defaultRadius;
        if (el('mcs-subject')) el('mcs-subject').value = _settings.defaultSubject;
        if (el('mcs-body')) el('mcs-body').value = _settings.defaultBody;
        if (el('mcs-expiration')) el('mcs-expiration').value = _settings.expirationDays;
        if (el('mcs-dynamic')) {
            el('mcs-dynamic').checked = _settings.dynamicSize;
            const radiusRow = el('mcs-radius-row');
            if (radiusRow) {
                radiusRow.style.display = _settings.dynamicSize ? 'none' : 'flex';
            }
        }
        // Vorlagen-Dropdown aktualisieren
        updateTemplateDropdown();
        // Custom Shapes Dropdown aktualisieren
        updateCustomShapesDropdown();
    }

    // ============ TEMPLATES ============

    function updateTemplateDropdown() {
        const select = document.getElementById('mcs-template-select');
        if (!select) return;

        // Aktuelle Auswahl merken
        const currentValue = select.value;

        // Dropdown leeren und neu befüllen
        select.innerHTML = `<option value="">${t('selectTemplate')}</option>`;

        if (_settings.templates && _settings.templates.length > 0) {
            _settings.templates.forEach((tpl, index) => {
                const option = document.createElement('option');
                option.value = index;
                option.textContent = tpl.name || `Template ${index + 1}`;
                select.appendChild(option);
            });
        }

        // Auswahl wiederherstellen falls möglich
        if (currentValue && select.querySelector(`option[value="${currentValue}"]`)) {
            select.value = currentValue;
        }
    }

    function saveTemplate() {
        const nameInput = document.getElementById('mcs-template-name');
        const subjectInput = document.getElementById('mcs-subject');
        const bodyInput = document.getElementById('mcs-body');

        const name = nameInput?.value?.trim();
        const subject = subjectInput?.value || '';
        const body = bodyInput?.value || '';

        if (!name) {
            updateStatus('⚠️ ' + t('enterTemplateName'));
            return;
        }

        if (!subject && !body) {
            updateStatus('⚠️ ' + t('enterTitleOrDesc'));
            return;
        }

        // Prüfen ob Name schon existiert
        const existingIndex = _settings.templates.findIndex(tpl => tpl.name === name);
        if (existingIndex >= 0) {
            // Überschreiben
            _settings.templates[existingIndex] = { name, subject, body };
            updateStatus('✅ ' + t('templateUpdated', { name }));
        } else {
            // Neu hinzufügen
            _settings.templates.push({ name, subject, body });
            updateStatus('✅ ' + t('templateSaved', { name }));
        }

        // Speichern und UI aktualisieren
        localStorage.setItem('WME_MapCommentShapes', JSON.stringify(_settings));
        updateTemplateDropdown();

        // Name-Feld leeren
        if (nameInput) nameInput.value = '';
    }

    function loadTemplate() {
        const select = document.getElementById('mcs-template-select');
        const index = parseInt(select?.value);

        if (isNaN(index) || !_settings.templates[index]) {
            updateStatus('⚠️ ' + t('noTemplateSelected'));
            return;
        }

        const tpl = _settings.templates[index];
        const subjectInput = document.getElementById('mcs-subject');
        const bodyInput = document.getElementById('mcs-body');

        if (subjectInput) subjectInput.value = tpl.subject || '';
        if (bodyInput) bodyInput.value = tpl.body || '';

        updateStatus('📋 ' + t('templateLoaded', { name: tpl.name }));
    }

    function deleteTemplate() {
        const select = document.getElementById('mcs-template-select');
        const index = parseInt(select?.value);

        if (isNaN(index) || !_settings.templates[index]) {
            updateStatus('⚠️ ' + t('noTemplateSelected'));
            return;
        }

        const name = _settings.templates[index].name;

        if (confirm(t('confirmDelete', { name }))) {
            _settings.templates.splice(index, 1);
            localStorage.setItem('WME_MapCommentShapes', JSON.stringify(_settings));
            updateTemplateDropdown();
            updateStatus('🗑️ ' + t('templateDeleted', { name }));
        }
    }

    // ============ SIMPLIFY ============

    function getSelectedMapComment() {
        try {
            // Versuche über Selection API
            const selection = W.selectionManager?.getSelectedDataModelObjects?.();
            if (selection && selection.length > 0) {
                const selected = selection[0];
                if (selected.type === 'mapComment' || selected.CLASS_NAME?.includes('MapComment')) {
                    return selected;
                }
            }

            // Alternative: über W.model
            const selectedItems = W.selectionManager?.getSelectedFeatures?.();
            if (selectedItems && selectedItems.length > 0) {
                const feature = selectedItems[0];
                if (feature.model?.type === 'mapComment') {
                    return feature.model;
                }
            }

            return null;
        } catch (e) {
            console.warn(`${SCRIPT_NAME} - Error getting selected comment:`, e);
            return null;
        }
    }

    function getCommentGeometry(comment) {
        try {
            // OL Geometry zuerst versuchen (gibt Mercator-Koordinaten)
            let olGeom = null;
            if (comment.getOLGeometry) {
                olGeom = comment.getOLGeometry();
            } else if (comment.geometry && comment.geometry.CLASS_NAME) {
                olGeom = comment.geometry;
            }

            if (olGeom && olGeom.getVertices) {
                // OpenLayers Polygon - Vertices extrahieren
                const vertices = olGeom.getVertices();
                if (vertices && vertices.length > 0) {
                    // Mercator zu WGS84 konvertieren
                    const wgs84Coords = vertices.map(v => mercatorToWgs84(v.x, v.y));
                    // Polygon schließen
                    if (wgs84Coords.length > 0) {
                        wgs84Coords.push(wgs84Coords[0]);
                    }
                    return [wgs84Coords];
                }
            }

            // GeoJSON Format versuchen
            if (comment.getGeometry) {
                const geom = comment.getGeometry();
                if (geom?.coordinates) return geom.coordinates;
            }
            if (comment.geometry?.coordinates) {
                return comment.geometry.coordinates;
            }
            if (comment.attributes?.geometry?.coordinates) {
                return comment.attributes.geometry.coordinates;
            }

            return null;
        } catch (e) {
            console.warn(`${SCRIPT_NAME} - Error getting geometry:`, e);
            return null;
        }
    }

    // Mercator (EPSG:3857) zu WGS84 (EPSG:4326)
    function mercatorToWgs84(x, y) {
        const lon = (x / 20037508.34) * 180;
        let lat = (y / 20037508.34) * 180;
        lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2);
        return [lon, lat];
    }

    // WGS84 (EPSG:4326) zu Mercator (EPSG:3857)
    function wgs84ToMercator(lon, lat) {
        const x = lon * 20037508.34 / 180;
        let y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
        y = y * 20037508.34 / 180;
        return [x, y];
    }

    function updateSimplifyInfo(original, simplified) {
        const infoEl = document.getElementById('mcs-simplify-info');
        if (!infoEl) return;

        const reduction = ((1 - simplified.length / original.length) * 100).toFixed(1);
        infoEl.innerHTML = `
            <span class="mcs-info-item">${t('before')} <b>${original.length}</b> ${t('points')}</span>
            <span class="mcs-info-item">${t('after')} <b>${simplified.length}</b> ${t('points')}</span>
            <span class="mcs-info-item mcs-reduction">${t('reduction')} <b>${reduction}%</b></span>
        `;
    }

    function previewSimplify() {
        const comment = getSelectedMapComment();
        if (!comment) {
            updateStatus('⚠️ ' + t('selectMapComment'));
            return;
        }

        const coords = getCommentGeometry(comment);
        if (!coords || !coords[0] || coords[0].length < 4) {
            updateStatus('⚠️ ' + t('noValidPolygon'));
            return;
        }

        const tolerance = parseInt(document.getElementById('mcs-simplify-tolerance')?.value) || 5;
        const highQuality = document.getElementById('mcs-simplify-hq')?.checked ?? true;

        const originalCoords = coords[0];
        const simplifiedCoords = simplify(originalCoords, tolerance, highQuality);

        // Polygon schließen falls nötig
        if (simplifiedCoords.length > 0 &&
            (simplifiedCoords[0][0] !== simplifiedCoords[simplifiedCoords.length-1][0] ||
             simplifiedCoords[0][1] !== simplifiedCoords[simplifiedCoords.length-1][1])) {
            simplifiedCoords.push(simplifiedCoords[0]);
        }

        updateSimplifyInfo(originalCoords, simplifiedCoords);
        updatePreview(simplifiedCoords);
        updateStatus('👁️ ' + t('preview', { from: originalCoords.length, to: simplifiedCoords.length }));
    }

    function simplifySelectedComment() {
        const comment = getSelectedMapComment();
        console.log(`${SCRIPT_NAME} - DEBUG: Selected comment:`, comment);

        if (!comment) {
            updateStatus('⚠️ ' + t('selectMapComment'));
            return;
        }

        console.log(`${SCRIPT_NAME} - DEBUG: Comment type:`, comment.type, comment.CLASS_NAME);
        console.log(`${SCRIPT_NAME} - DEBUG: Comment attributes:`, comment.attributes);

        const coords = getCommentGeometry(comment);
        console.log(`${SCRIPT_NAME} - DEBUG: Geometry coords:`, coords);

        if (!coords || !coords[0] || coords[0].length < 4) {
            updateStatus('⚠️ ' + t('noValidPolygon'));
            return;
        }

        const tolerance = parseInt(document.getElementById('mcs-simplify-tolerance')?.value) || 5;
        const highQuality = document.getElementById('mcs-simplify-hq')?.checked ?? true;

        const originalCoords = coords[0];
        const simplifiedCoords = simplify(originalCoords, tolerance, highQuality);

        console.log(`${SCRIPT_NAME} - DEBUG: Original coords sample:`, originalCoords.slice(0, 3));
        console.log(`${SCRIPT_NAME} - DEBUG: Simplified coords sample:`, simplifiedCoords.slice(0, 3));

        // Mindestens 3 Punkte + Schlusspunkt
        if (simplifiedCoords.length < 4) {
            updateStatus('⚠️ ' + t('tooFewPoints'));
            return;
        }

        // Polygon schließen falls nötig
        if (simplifiedCoords[0][0] !== simplifiedCoords[simplifiedCoords.length-1][0] ||
            simplifiedCoords[0][1] !== simplifiedCoords[simplifiedCoords.length-1][1]) {
            simplifiedCoords.push(simplifiedCoords[0]);
        }

        try {
            // WME erwartet OpenLayers Geometry in Mercator (EPSG:3857)

            // Konvertiere WGS84 (lon/lat) zu Mercator und erstelle OL Points
            const mercatorCoords = simplifiedCoords.map(coord => {
                const [x, y] = wgs84ToMercator(coord[0], coord[1]);
                return new OpenLayers.Geometry.Point(x, y);
            });

            console.log(`${SCRIPT_NAME} - DEBUG: Mercator coords sample:`, mercatorCoords.slice(0, 2).map(p => ({x: p.x, y: p.y})));

            // Neues Polygon erstellen
            const ring = new OpenLayers.Geometry.LinearRing(mercatorCoords);
            const newOLGeometry = new OpenLayers.Geometry.Polygon([ring]);

            console.log(`${SCRIPT_NAME} - DEBUG: New OL Geometry:`, newOLGeometry);

            // Geometrie direkt setzen
            if (comment.setOLGeometry) {
                console.log(`${SCRIPT_NAME} - DEBUG: Using setOLGeometry`);
                comment.setOLGeometry(newOLGeometry);

                // WME über Änderung informieren - Feature neu zeichnen
                if (W.model.mapComments) {
                    W.model.mapComments.trigger('objectschanged', [comment]);
                }

                // Save-Button aktivieren durch Markieren als geändert
                if (comment.state !== 'Update') {
                    comment.state = 'Update';
                }
            } else {
                throw new Error('setOLGeometry nicht verfügbar');
            }

            clearPreview();
            updateSimplifyInfo(originalCoords, simplifiedCoords);
            updateStatus('✅ ' + t('simplified', { from: originalCoords.length, to: simplifiedCoords.length }));
            console.log(`${SCRIPT_NAME} - Simplified: ${originalCoords.length} → ${simplifiedCoords.length} points`);

        } catch (e) {
            console.error(`${SCRIPT_NAME} - Simplify error:`, e);
            console.error(`${SCRIPT_NAME} - Error stack:`, e.stack);
            updateStatus('❌ ' + t('simplifyError') + ' ' + e.message);
        }
    }

    // ============ ROTATE ============

    function rotatePoint(point, center, angleDeg) {
        const angleRad = toRadians(angleDeg);

        // Konvertiere zu lokalen Koordinaten (Meter)
        const avgLat = center[1];
        const lonScale = 111000 * Math.cos(toRadians(avgLat));
        const latScale = 111000;

        const dx = (point[0] - center[0]) * lonScale;
        const dy = (point[1] - center[1]) * latScale;

        // Rotieren
        const rx = dx * Math.cos(angleRad) - dy * Math.sin(angleRad);
        const ry = dx * Math.sin(angleRad) + dy * Math.cos(angleRad);

        // Zurück zu Geo-Koordinaten
        return [
            center[0] + rx / lonScale,
            center[1] + ry / latScale
        ];
    }

    function getPolygonCenter(coords) {
        let sumLon = 0, sumLat = 0;
        const n = coords.length - 1; // Letzter Punkt = erster Punkt
        for (let i = 0; i < n; i++) {
            sumLon += coords[i][0];
            sumLat += coords[i][1];
        }
        return [sumLon / n, sumLat / n];
    }

    function rotateCoords(coords, angleDeg) {
        const center = getPolygonCenter(coords);
        return coords.map(coord => rotatePoint(coord, center, angleDeg));
    }

    function previewRotate() {
        const comment = getSelectedMapComment();
        if (!comment) {
            updateStatus('⚠️ ' + t('selectMapComment'));
            return;
        }

        const coords = getCommentGeometry(comment);
        if (!coords || !coords[0] || coords[0].length < 4) {
            updateStatus('⚠️ ' + t('noValidPolygon'));
            return;
        }

        const angle = parseInt(document.getElementById('mcs-rotate-angle')?.value) || 45;
        const rotatedCoords = rotateCoords(coords[0], angle);

        updatePreview(rotatedCoords);
        updateStatus('👁️ ' + t('rotated', { angle }));
    }

    function rotateSelectedComment() {
        const comment = getSelectedMapComment();
        if (!comment) {
            updateStatus('⚠️ ' + t('selectMapComment'));
            return;
        }

        const coords = getCommentGeometry(comment);
        if (!coords || !coords[0] || coords[0].length < 4) {
            updateStatus('⚠️ ' + t('noValidPolygon'));
            return;
        }

        const angle = parseInt(document.getElementById('mcs-rotate-angle')?.value) || 45;
        const rotatedCoords = rotateCoords(coords[0], angle);

        try {
            // Konvertiere zu Mercator und erstelle OL Geometry
            const mercatorCoords = rotatedCoords.map(coord => {
                const [x, y] = wgs84ToMercator(coord[0], coord[1]);
                return new OpenLayers.Geometry.Point(x, y);
            });

            const ring = new OpenLayers.Geometry.LinearRing(mercatorCoords);
            const newOLGeometry = new OpenLayers.Geometry.Polygon([ring]);

            if (comment.setOLGeometry) {
                comment.setOLGeometry(newOLGeometry);

                if (W.model.mapComments) {
                    W.model.mapComments.trigger('objectschanged', [comment]);
                }

                if (comment.state !== 'Update') {
                    comment.state = 'Update';
                }
            }

            clearPreview();
            updateStatus('✅ ' + t('rotated', { angle }));
            console.log(`${SCRIPT_NAME} - Rotated by ${angle}°`);

        } catch (e) {
            console.error(`${SCRIPT_NAME} - Rotate error:`, e);
            updateStatus('❌ ' + t('error') + ' ' + e.message);
        }
    }

    // ============ CUSTOM SHAPES ============

    function updateCustomShapesDropdown() {
        const select = document.getElementById('mcs-custom-select');
        if (!select) return;

        const currentValue = select.value;
        select.innerHTML = `<option value="">${t('selectCustomShape')}</option>`;

        if (_settings.customShapes && _settings.customShapes.length > 0) {
            _settings.customShapes.forEach((shape, index) => {
                const option = document.createElement('option');
                option.value = index;
                option.textContent = shape.name || `Shape ${index + 1}`;
                select.appendChild(option);
            });
        }

        if (currentValue && select.querySelector(`option[value="${currentValue}"]`)) {
            select.value = currentValue;
        }
    }

    function normalizeCoords(coords) {
        // Normalisiere Koordinaten auf -1 bis 1 relativ zum Zentrum
        const center = getPolygonCenter(coords);
        const avgLat = center[1];
        const lonScale = 111000 * Math.cos(toRadians(avgLat));
        const latScale = 111000;

        // Finde maximale Ausdehnung
        let maxDist = 0;
        for (const coord of coords) {
            const dx = (coord[0] - center[0]) * lonScale;
            const dy = (coord[1] - center[1]) * latScale;
            const dist = Math.sqrt(dx * dx + dy * dy);
            if (dist > maxDist) maxDist = dist;
        }

        if (maxDist === 0) maxDist = 1;

        // Normalisiere
        return coords.map(coord => {
            const dx = (coord[0] - center[0]) * lonScale / maxDist;
            const dy = (coord[1] - center[1]) * latScale / maxDist;
            return [dx, dy];
        });
    }

    function denormalizeCoords(normalizedCoords, center, radius) {
        const avgLat = center[1];
        const lonScale = 111000 * Math.cos(toRadians(avgLat));
        const latScale = 111000;

        return normalizedCoords.map(([nx, ny]) => {
            const lon = center[0] + (nx * radius) / lonScale;
            const lat = center[1] + (ny * radius) / latScale;
            return [lon, lat];
        });
    }

    function saveCustomShape() {
        const nameInput = document.getElementById('mcs-custom-name');
        const name = nameInput?.value?.trim();

        if (!name) {
            updateStatus('⚠️ ' + t('enterShapeName'));
            return;
        }

        const comment = getSelectedMapComment();
        if (!comment) {
            updateStatus('⚠️ ' + t('selectMapComment'));
            return;
        }

        const coords = getCommentGeometry(comment);
        if (!coords || !coords[0] || coords[0].length < 4) {
            updateStatus('⚠️ ' + t('noValidPolygon'));
            return;
        }

        // Normalisiere die Koordinaten
        const normalizedCoords = normalizeCoords(coords[0]);

        // Prüfen ob Name schon existiert
        const existingIndex = _settings.customShapes.findIndex(s => s.name === name);
        if (existingIndex >= 0) {
            _settings.customShapes[existingIndex] = { name, coords: normalizedCoords };
        } else {
            _settings.customShapes.push({ name, coords: normalizedCoords });
        }

        localStorage.setItem('WME_MapCommentShapes', JSON.stringify(_settings));
        updateCustomShapesDropdown();
        updateStatus('✅ ' + t('shapeSaved', { name }));

        if (nameInput) nameInput.value = '';
    }

    function useCustomShape() {
        const select = document.getElementById('mcs-custom-select');
        const index = parseInt(select?.value);

        if (isNaN(index) || !_settings.customShapes[index]) {
            updateStatus('⚠️ ' + t('noTemplateSelected'));
            return;
        }

        const shape = _settings.customShapes[index];
        customShapeCoords = shape.coords;

        // Starte Zeichenmodus mit Custom Shape
        drawingMode = SHAPES.CUSTOM;
        isDrawing = true;
        shapeCenter = null;

        const cancelBtn = document.getElementById('mcs-cancel');
        if (cancelBtn) cancelBtn.style.display = 'inline-block';

        document.querySelectorAll('.mcs-btn').forEach(b => b.classList.remove('active'));

        const isDynamic = document.getElementById('mcs-dynamic')?.checked;
        if (isDynamic) {
            updateStatus(t('clickForCenter', { shape: shape.name }));
        } else {
            updateStatus(t('clickForPosition', { shape: shape.name }));
        }

        document.body.classList.add('mcs-drawing-mode');
        sdk.Events.on({ eventName: 'wme-map-mouse-up', eventHandler: onMapClick });
        sdk.Events.on({ eventName: 'wme-map-mouse-move', eventHandler: onMapMouseMove });

        updateStatus('✅ ' + t('customShapeLoaded') + ': ' + shape.name);
    }

    function deleteCustomShape() {
        const select = document.getElementById('mcs-custom-select');
        const index = parseInt(select?.value);

        if (isNaN(index) || !_settings.customShapes[index]) {
            updateStatus('⚠️ ' + t('noTemplateSelected'));
            return;
        }

        const name = _settings.customShapes[index].name;

        if (confirm(t('confirmDeleteShape', { name }))) {
            _settings.customShapes.splice(index, 1);
            localStorage.setItem('WME_MapCommentShapes', JSON.stringify(_settings));
            updateCustomShapesDropdown();
            updateStatus('🗑️ ' + t('shapeDeleted', { name }));
        }
    }

    function createCustomShapeCoords(center, radius) {
        if (!customShapeCoords) return null;
        return denormalizeCoords(customShapeCoords, center, radius);
    }

    // ============ DRAWING ============

    function startDrawing(shape) {
        isDrawing = true;
        drawingMode = shape;
        drawPoints = [];
        shapeCenter = null;

        const cancelBtn = document.getElementById('mcs-cancel');
        const finishBtn = document.getElementById('mcs-finish');

        if (cancelBtn) cancelBtn.style.display = 'inline-block';
        if (finishBtn) finishBtn.style.display = 'none';

        const isDynamic = document.getElementById('mcs-dynamic')?.checked;
        const isShapeWithRadius = [SHAPES.CIRCLE, SHAPES.SQUARE, SHAPES.RECTANGLE, SHAPES.TRIANGLE,
                                   SHAPES.PENTAGON, SHAPES.HEXAGON, SHAPES.OCTAGON, SHAPES.STAR,
                                   SHAPES.ARROW_UP, SHAPES.ARROW_DOWN, SHAPES.ARROW_LEFT, SHAPES.ARROW_RIGHT,
                                   SHAPES.SPEECH_RECT, SHAPES.SPEECH_ROUND, SHAPES.CUSTOM].includes(shape);

        const shapeName = getShapeName(shape);
        let statusMsg;
        if (isDynamic && isShapeWithRadius) {
            statusMsg = t('clickForCenter', { shape: shapeName });
        } else {
            statusMsg = t('clickForPosition', { shape: shapeName });
        }

        updateStatus(statusMsg);
        document.body.classList.add('mcs-drawing-mode');

        // SDK Events registrieren
        sdk.Events.on({ eventName: 'wme-map-mouse-up', eventHandler: onMapClick });
        sdk.Events.on({ eventName: 'wme-map-mouse-move', eventHandler: onMapMouseMove });
    }

    function cancelDrawing() {
        isDrawing = false;
        drawingMode = null;
        drawPoints = [];
        shapeCenter = null;

        document.querySelectorAll('.mcs-btn').forEach(b => b.classList.remove('active'));

        const cancelBtn = document.getElementById('mcs-cancel');
        const finishBtn = document.getElementById('mcs-finish');
        if (cancelBtn) cancelBtn.style.display = 'none';
        if (finishBtn) finishBtn.style.display = 'none';

        updateStatus(t('defaultStatus'));
        document.body.classList.remove('mcs-drawing-mode');
        clearPreview();

        // Event Listener entfernen
        sdk.Events.off({ eventName: 'wme-map-mouse-up', eventHandler: onMapClick });
        sdk.Events.off({ eventName: 'wme-map-mouse-move', eventHandler: onMapMouseMove });
    }

    function updateStatus(msg) {
        const el = document.getElementById('mcs-status');
        if (el) el.textContent = msg;
    }

    // Echtzeit-Vorschau bei Mausbewegung
    function onMapMouseMove(event) {
        // Debug: Prüfen ob Funktion aufgerufen wird
        if (!onMapMouseMove.callCount) onMapMouseMove.callCount = 0;
        onMapMouseMove.callCount++;

        if (onMapMouseMove.callCount % 100 === 1) {
            console.log(`${SCRIPT_NAME} - MouseMove called (${onMapMouseMove.callCount}x), isDrawing=${isDrawing}, shapeCenter=${JSON.stringify(shapeCenter)}`);
        }

        if (!isDrawing || !shapeCenter) return;

        const isDynamic = document.getElementById('mcs-dynamic')?.checked;
        if (!isDynamic) return;

        let coords;
        if (event.lon !== undefined && event.lat !== undefined) {
            coords = [Number(event.lon), Number(event.lat)];
        }
        if (!coords || isNaN(coords[0]) || isNaN(coords[1])) return;

        const radius = distanceBetween(shapeCenter, coords);

        // Debug: Nur alle 500ms loggen um Console nicht zu fluten
        if (!onMapMouseMove.lastLog || Date.now() - onMapMouseMove.lastLog > 500) {
            console.log(`${SCRIPT_NAME} - Preview: center=${JSON.stringify(shapeCenter)}, mouse=${JSON.stringify(coords)}, radius=${radius.toFixed(1)}m`);
            onMapMouseMove.lastLog = Date.now();
        }

        const previewCoords = getShapeCoords(shapeCenter, radius);

        if (previewCoords && previewCoords.length >= 3) {
            updatePreview(previewCoords);
            updateStatus(t('radiusDisplay', { radius: Math.round(radius) }));
        }
    }

    // Hilfsfunktion: Koordinaten für aktuelle Form berechnen
    function getShapeCoords(center, radius) {
        switch (drawingMode) {
            case SHAPES.CIRCLE:
                return createCircleCoords(center, radius, 32);
            case SHAPES.SQUARE:
                return createRegularPolygonCoords(center, radius, 4, 45);
            case SHAPES.RECTANGLE:
                return createRectangleCoords(center, radius);
            case SHAPES.TRIANGLE:
                return createRegularPolygonCoords(center, radius, 3, 0);
            case SHAPES.PENTAGON:
                return createRegularPolygonCoords(center, radius, 5, -18);
            case SHAPES.HEXAGON:
                return createRegularPolygonCoords(center, radius, 6, 0);
            case SHAPES.OCTAGON:
                return createRegularPolygonCoords(center, radius, 8, 22.5);
            case SHAPES.STAR:
                return createStarCoords(center, radius, 5);
            case SHAPES.ARROW_UP:
                return createArrowCoords(center, radius, 0);
            case SHAPES.ARROW_DOWN:
                return createArrowCoords(center, radius, 180);
            case SHAPES.ARROW_LEFT:
                return createArrowCoords(center, radius, 90);
            case SHAPES.ARROW_RIGHT:
                return createArrowCoords(center, radius, 270);
            case SHAPES.SPEECH_RECT:
                return createSpeechRectCoords(center, radius);
            case SHAPES.SPEECH_ROUND:
                return createSpeechRoundCoords(center, radius);
            case SHAPES.CUSTOM:
                return createCustomShapeCoords(center, radius);
            default:
                return null;
        }
    }

    function onMapClick(event) {
        if (!isDrawing || !drawingMode) return;

        let coords;
        if (event.lon !== undefined && event.lat !== undefined) {
            // Sicherstellen dass es Numbers sind
            coords = [Number(event.lon), Number(event.lat)];
        } else if (event.coordinates && event.coordinates.length >= 2) {
            coords = [Number(event.coordinates[0]), Number(event.coordinates[1])];
        }

        if (!coords || isNaN(coords[0]) || isNaN(coords[1])) {
            console.warn(`${SCRIPT_NAME} - Could not get valid coordinates from event:`, event);
            return;
        }

        console.log(`${SCRIPT_NAME} - Click at:`, coords, `(types: ${typeof coords[0]}, ${typeof coords[1]})`);

        const isDynamic = document.getElementById('mcs-dynamic')?.checked;

        switch (drawingMode) {
            case SHAPES.POINT:
                createPointComment(coords);
                cancelDrawing();
                break;

            case SHAPES.CIRCLE:
            case SHAPES.SQUARE:
            case SHAPES.RECTANGLE:
            case SHAPES.TRIANGLE:
            case SHAPES.PENTAGON:
            case SHAPES.HEXAGON:
            case SHAPES.OCTAGON:
            case SHAPES.STAR:
            case SHAPES.ARROW_UP:
            case SHAPES.ARROW_DOWN:
            case SHAPES.ARROW_LEFT:
            case SHAPES.ARROW_RIGHT:
            case SHAPES.SPEECH_RECT:
            case SHAPES.SPEECH_ROUND:
            case SHAPES.CUSTOM:
                if (isDynamic) {
                    if (!shapeCenter) {
                        shapeCenter = [coords[0], coords[1]]; // Explizite Kopie
                        console.log(`${SCRIPT_NAME} - Shape center set:`, shapeCenter);
                        updateStatus(t('moveForSize'));
                    } else {
                        const radius = distanceBetween(shapeCenter, coords);
                        console.log(`${SCRIPT_NAME} - Dynamic radius: ${radius.toFixed(1)}m from center ${JSON.stringify(shapeCenter)} to ${JSON.stringify(coords)}`);
                        createShapeCommentWithRadius(shapeCenter, radius);
                        cancelDrawing();
                    }
                } else {
                    createShapeComment(coords);
                    cancelDrawing();
                }
                break;
        }
    }

    // ============ MAP COMMENT CREATION ============

    function getCommentData() {
        const subject = document.getElementById('mcs-subject')?.value || 'Map Comment';
        const body = document.getElementById('mcs-body')?.value || '';
        const days = parseInt(document.getElementById('mcs-expiration')?.value) || 30;
        const endDate = Date.now() + (days * 24 * 60 * 60 * 1000);

        return { subject, body, endDate };
    }

    function createPointComment(coords) {
        const { subject, body, endDate } = getCommentData();

        const geometry = {
            type: 'Point',
            coordinates: coords
        };

        addMapComment(geometry, subject, body, endDate);
    }

    function createShapeComment(center) {
        const radius = parseInt(document.getElementById('mcs-radius')?.value) || 50;
        createShapeCommentWithRadius(center, radius);
    }

    function createShapeCommentWithRadius(center, radius) {
        const { subject, body, endDate } = getCommentData();

        // Sicherstellen dass center Numbers enthält
        const safeCenter = [parseFloat(center[0]), parseFloat(center[1])];

        // Mindestradius 5m
        const safeRadius = Math.max(5, parseFloat(radius));

        let coords = getShapeCoords(safeCenter, safeRadius);
        if (!coords) return;

        const geometry = {
            type: 'Polygon',
            coordinates: [coords]
        };

        clearPreview();
        addMapComment(geometry, subject, body, endDate);
    }

    function addMapComment(geometry, subject, body, endDate) {
        try {
            let cleanGeometry;

            if (geometry.type === 'Point') {
                // Point: coordinates ist direkt [lon, lat]
                cleanGeometry = {
                    type: 'Point',
                    coordinates: [Number(geometry.coordinates[0]), Number(geometry.coordinates[1])]
                };
            } else {
                // Polygon: coordinates ist [[...points...]]
                const coords = geometry.coordinates[0].map(coord => {
                    if (Array.isArray(coord)) {
                        return [Number(coord[0]), Number(coord[1])];
                    }
                    return coord;
                });
                cleanGeometry = {
                    type: 'Polygon',
                    coordinates: [coords]
                };
            }

            console.log(`${SCRIPT_NAME} - Creating map comment with geometry:`, JSON.stringify(cleanGeometry));

            const result = sdk.DataModel.MapComments.addComment({
                geometry: cleanGeometry,
                subject: String(subject).substring(0, 30),
                body: String(body).substring(0, 2000),
                endDate: Number(endDate)
            });

            if (result) {
                updateStatus('✅ ' + t('commentCreatedId', { id: result.id }));
                console.log(`${SCRIPT_NAME} - Map comment created:`, result);

                // Neu erstellten Map Comment automatisch auswählen
                setTimeout(() => {
                    try {
                        if (W.selectionManager && result) {
                            // Versuche den Comment zu finden und auszuwählen
                            const comment = W.model.mapComments.getObjectById(result.id);
                            if (comment) {
                                W.selectionManager.setSelectedModels([comment]);
                                console.log(`${SCRIPT_NAME} - Auto-selected created comment:`, result.id);

                                // Tab wieder auf unser Script setzen (WME springt automatisch zum Edit-Tab)
                                setTimeout(() => {
                                    try {
                                        // Versuche verschiedene Selektoren
                                        const tabSelectors = [
                                            `#user-tabs [data-tab-id="${SCRIPT_ID}"]`,
                                            `#sidepanel-scripts [data-tab-id="${SCRIPT_ID}"]`,
                                            `.nav-tabs [data-tab-id="${SCRIPT_ID}"]`,
                                            `[id*="${SCRIPT_ID}"]`,
                                            `a[href="#${SCRIPT_ID}"]`
                                        ];

                                        let clicked = false;
                                        for (const selector of tabSelectors) {
                                            const tab = document.querySelector(selector);
                                            if (tab) {
                                                tab.click();
                                                clicked = true;
                                                console.log(`${SCRIPT_NAME} - Restored script tab via:`, selector);
                                                break;
                                            }
                                        }

                                        // Fallback: Suche nach Tab mit unserem Emoji
                                        if (!clicked) {
                                            const allTabs = document.querySelectorAll('#user-tabs .nav-tabs li a, #sidepanel-scripts .nav-tabs li a');
                                            for (const tab of allTabs) {
                                                if (tab.textContent.includes('📝') || tab.title?.includes('Map Comment')) {
                                                    tab.click();
                                                    console.log(`${SCRIPT_NAME} - Restored script tab via emoji search`);
                                                    break;
                                                }
                                            }
                                        }
                                    } catch (e) {
                                        console.warn(`${SCRIPT_NAME} - Could not restore tab:`, e);
                                    }
                                }, 150);
                            }
                        }
                    } catch (e) {
                        console.warn(`${SCRIPT_NAME} - Could not auto-select comment:`, e);
                    }
                }, 100); // Kurze Verzögerung damit der Comment vollständig erstellt ist

            } else {
                updateStatus('⚠️ ' + t('commentCreated'));
            }

        } catch (err) {
            console.error(`${SCRIPT_NAME} - Error:`, err);
            updateStatus('❌ ' + t('error') + ' ' + err.message);
        }
    }

    // ============ STYLES ============

    function injectStyles() {
        if (document.getElementById('mcs-styles')) return;

        const style = document.createElement('style');
        style.id = 'mcs-styles';
        style.textContent = `
            .mcs-container {
                padding: 10px;
                font-family: 'Segoe UI', Tahoma, sans-serif;
                font-size: 13px;
            }
            .mcs-container h4 {
                margin: 0 0 5px 0;
                color: #333;
            }
            .mcs-version {
                color: #888;
                font-size: 11px;
                margin: 0 0 15px 0;
            }
            .mcs-section {
                margin-bottom: 15px;
            }
            .mcs-label {
                display: block;
                font-weight: bold;
                margin-bottom: 8px;
                color: #444;
            }
            .mcs-shape-grid {
                display: grid;
                grid-template-columns: repeat(3, 1fr);
                gap: 5px;
            }
            .mcs-shape-grid.mcs-arrows {
                grid-template-columns: repeat(4, 1fr);
                margin-top: 5px;
            }
            .mcs-shape-grid.mcs-speech {
                grid-template-columns: repeat(2, 1fr);
                margin-top: 5px;
            }
            .mcs-sublabel {
                margin-top: 10px;
                font-size: 11px;
                color: #666;
            }
            .mcs-btn {
                padding: 8px;
                font-size: 18px;
                border: 2px solid #ddd;
                border-radius: 5px;
                background: #f5f5f5;
                cursor: pointer;
                transition: all 0.15s;
            }
            .mcs-btn:hover {
                background: #e8e8e8;
                border-color: #4a90d9;
            }
            .mcs-btn.active {
                background: #4a90d9;
                border-color: #357abd;
                color: white;
            }
            .mcs-row {
                display: flex;
                align-items: center;
                gap: 8px;
                margin-bottom: 5px;
            }
            .mcs-row span {
                min-width: 70px;
                color: #555;
            }
            .mcs-row input[type="number"] {
                width: 60px;
                padding: 4px;
                border: 1px solid #ccc;
                border-radius: 3px;
            }
            .mcs-checkbox {
                display: flex;
                align-items: center;
                gap: 6px;
                cursor: pointer;
                color: #555;
            }
            .mcs-checkbox input {
                cursor: pointer;
            }
            .mcs-select {
                flex: 1;
                padding: 4px;
                border: 1px solid #ccc;
                border-radius: 3px;
                font-size: 12px;
            }
            .mcs-small-btn {
                padding: 4px 8px;
                border: 1px solid #ccc;
                border-radius: 3px;
                background: #f5f5f5;
                cursor: pointer;
                font-size: 14px;
                transition: all 0.15s;
            }
            .mcs-small-btn:hover {
                background: #e8e8e8;
            }
            .mcs-small-btn.mcs-save {
                background: #d4edda;
                border-color: #28a745;
            }
            .mcs-small-btn.mcs-save:hover {
                background: #c3e6cb;
            }
            .mcs-small-btn.mcs-delete {
                background: #f8d7da;
                border-color: #dc3545;
            }
            .mcs-small-btn.mcs-delete:hover {
                background: #f5c6cb;
            }
            .mcs-template-input {
                flex: 1;
                padding: 4px 6px;
                border: 1px solid #ccc;
                border-radius: 3px;
                font-size: 12px;
            }
            .mcs-row-full {
                margin-bottom: 8px;
            }
            .mcs-row-full input,
            .mcs-row-full textarea {
                width: 100%;
                padding: 6px;
                border: 1px solid #ccc;
                border-radius: 3px;
                font-family: inherit;
                font-size: 12px;
                box-sizing: border-box;
            }
            .mcs-row-full textarea {
                resize: vertical;
            }
            .mcs-status {
                background: #e8f4fc;
                border: 1px solid #b8d4e8;
                border-radius: 4px;
                padding: 8px;
                text-align: center;
                color: #2c5282;
                margin-bottom: 8px;
            }
            .mcs-actions {
                display: flex;
                gap: 8px;
                justify-content: center;
            }
            .mcs-action-btn {
                padding: 6px 14px;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-weight: bold;
                font-size: 12px;
            }
            .mcs-cancel {
                background: #dc3545;
                color: white;
            }
            .mcs-cancel:hover { background: #c82333; }
            .mcs-help {
                background: #fffbeb;
                border-radius: 4px;
                padding: 10px;
                margin-top: 10px;
            }
            .mcs-help ul {
                margin: 0;
                padding-left: 16px;
                font-size: 11px;
                color: #666;
            }
            .mcs-help li { margin-bottom: 3px; }
            .mcs-help b { color: #333; }

            /* Simplify Section */
            .mcs-simplify-section {
                background: #f0f7ff;
                border: 1px solid #b8d4e8;
                border-radius: 6px;
                padding: 10px;
            }
            .mcs-hint {
                font-size: 11px;
                color: #666;
                margin: 0 0 10px 0;
            }
            .mcs-hint-small {
                font-size: 10px;
                color: #888;
                margin: 5px 0 0 0;
            }
            .mcs-slider {
                flex: 1;
                cursor: pointer;
            }
            .mcs-simplify-actions, .mcs-rotate-actions {
                justify-content: center;
                gap: 10px;
                margin-top: 8px;
            }
            .mcs-simplify {
                background: #17a2b8;
                color: white;
                padding: 8px 16px;
            }
            .mcs-simplify:hover { background: #138496; }
            .mcs-simplify-info {
                margin-top: 8px;
                padding: 6px;
                background: #e8f4fc;
                border-radius: 4px;
                font-size: 11px;
                display: flex;
                flex-wrap: wrap;
                gap: 8px;
                justify-content: center;
            }
            .mcs-simplify-info:empty { display: none; }
            .mcs-info-item { color: #555; }
            .mcs-info-item b { color: #333; }
            .mcs-reduction b { color: #28a745; }

            /* Rotate Section */
            .mcs-rotate-section {
                background: #fff8e6;
                border: 1px solid #f0d78c;
                border-radius: 6px;
                padding: 10px;
            }
            .mcs-rotate {
                background: #ffc107;
                color: #333;
                padding: 8px 16px;
            }
            .mcs-rotate:hover { background: #e0a800; }

            /* Custom Shapes Section */
            .mcs-custom-section {
                background: #f0fff0;
                border: 1px solid #90ee90;
                border-radius: 6px;
                padding: 10px;
            }

            body.mcs-drawing-mode #WazeMap,
            body.mcs-drawing-mode #WazeMap * {
                cursor: crosshair !important;
            }
        `;
        document.head.appendChild(style);
    }

    // ============ START ============

    init();

})();