Bearbeiten von „OS2.jugend

Zur Navigation springen Zur Suche springen
Warnung: Du bist nicht angemeldet. Deine IP-Adresse wird bei Bearbeitungen öffentlich sichtbar. Melde dich an oder erstelle ein Benutzerkonto, damit Bearbeitungen deinem Benutzernamen zugeordnet werden. Ein eigenes Benutzerkonto hat eine ganze Reihe von Vorteilen.

Die Bearbeitung kann rückgängig gemacht werden. Bitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und veröffentliche dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.

Aktuelle Version Dein Text
Zeile 8: Zeile 8:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Version'''
| '''Version'''
| '''0.73 (WebExtensions)'''
| '''0.60 (WebExtensions)'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Autor'''
| '''Autor'''
Zeile 36: Zeile 36:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Funktionalität'''
| '''Funktionalität'''
| '''Trennstriche zwischen den Jahrgängen'''<br> '''Aktueller Skill, Opti und MW'''<br> '''Prognose von Opti und MW für Ende Jahrgang 18'''<br> '''Optionen und Menu'''<br> '''Neue Marktwertformel'''<br> '''Automatische Ermittlung des ZATs'''<br> '''Hidden-Optionen und Datenspeicher'''<br> '''Geburtstage und dezimales Alter'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Zusatzspalten Talent/Quote/Aufw./Geb./Alter'''<br> '''Zusatzspalten Quote/Alter/Pos in der Übersicht'''<br> '''Zusatzspalten Alter ersetzen/Aufwertungen kurz+TOR'''<br> '''Zusatzspalten fix/tr./%H/%N/Prios jetzt und Ende'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''<br> '''Qualitätsbalken'''<br> '''Markierung der Primärskills bei Einzelwerten und Aufwertungen'''<br> '''Beachtung von Jugendförderung und Doppelpositionen'''<br> '''Warnung vor Ende 18 in letzter Periode und mehr am letzten ZAT'''<br> '''Reguläre Ausdrücke im @include'''<br> '''Neues Design und Seite "Opt. Skill"'''<br> '''Gruppierung nach Jahrgängen U13 bis U18 (per Option)'''<br> '''Warnung vor Ende 18 auch im Managerbüro (per Option)'''<br> '''Warnung vor Sperre des Ziehens im Falle eines Aufstiegs'''<br> '''Neuer Jahrgang U19'''
| '''Trennstriche zwischen den Jahrgängen'''<br> '''Aktueller Skill, Opti und MW'''<br> '''Prognose von Opti und MW für Ende Jahrgang 18'''<br> '''Optionen und Menu'''<br> '''Neue Marktwertformel'''<br> '''Automatische Ermittlung des ZATs'''<br> '''Hidden-Optionen und Datenspeicher'''<br> '''Geburtstage und dezimales Alter'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Zusatzspalten Talent/Quote/Aufw./Geb./Alter'''<br> '''Zusatzspalten Quote/Alter/Pos in der Übersicht'''<br> '''Zusatzspalten Alter ersetzen/Aufwertungen kurz+TOR'''<br> '''Zusatzspalten fix/tr./%H/%N/Prios jetzt und Ende'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''<br> '''Qualitätsbalken'''<br> '''Markierung der Primärskills bei Einzelwerten und Aufwertungen'''<br> '''Beachtung von Jugendförderung und Doppelpositionen'''<br> '''Warnung vor Ende 18 in letzer Periode und mehr am letzten ZAT'''<br> '''Reguläre Ausdrücke im @include'''<br> '''Neues Design und Seite "Opt. Skill"'''


|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
Zeile 48: Zeile 48:
// @name        OS2.jugend
// @name        OS2.jugend
// @namespace    http://os.ongapo.com/
// @namespace    http://os.ongapo.com/
// @version      0.73
// @version      0.60
// @copyright    2013+
// @copyright    2013+
// @author      Sven Loges (SLC) / Andreas Eckes (Strindheim BK)
// @author      Sven Loges (SLC) / Andreas Eckes (Strindheim BK)
Zeile 124: Zeile 124:
                   'AltHotkey' : 'k',
                   'AltHotkey' : 'k',
                   'FormLabel' : "Prognose Einzelwerte"
                   'FormLabel' : "Prognose Einzelwerte"
              },
    'zeigeJahrgang' : {  // Auswahl, ob ueber jedem Jahrgang die Ueberschriften gezeigt werden sollen oder alles in einem Block (true = Jahrgaenge, false = ein Block)
                  'Name'      : "showGroupTitle",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Jahrgangs\xFCberschriften",
                  'Hotkey'    : 'J',
                  'AltLabel'  : "Nur Trennlinie benutzen",
                  'AltHotkey' : 'j',
                  'FormLabel' : "Jahrg\xE4nge gruppieren"
              },
    'zeigeUxx' : {        // Auswahl, ob in der Ueberschrift ueber jedem Jahrgang zusaetzlich zur Saison noch der Jahrgang in der Form 'Uxx' angegeben wird
                  'Name'      : "showUxx",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Jahrg\xE4nge anzeigen",
                  'Hotkey'    : 'U',
                  'AltLabel'  : "Nur Saisons anzeigen",
                  'AltHotkey' : 'u',
                  'FormLabel' : "Jahrg\xE4nge U13 bis U19"
              },
    'zeigeWarnung' : {    // Auswahl, ob eine Warnung erscheint, wenn Talente gezogen werden sollten
                  'Name'      : "showWarning",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung ein",
                  'Hotkey'    : 'Z',
                  'AltLabel'  : "Ziehwarnung aus",
                  'AltHotkey' : 'Z',
                  'FormLabel' : "Ziehwarnung"
              },
    'zeigeWarnungMonat' : {  // Auswahl, ob eine Warnung erscheint, wenn zum naechsten Abrechnungs-ZAT Talente gezogen werden sollten
                  'Name'      : "showWarningMonth",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung Monat ein",
                  'Hotkey'    : 'Z',
                  'AltLabel'  : "Ziehwarnung Monat aus",
                  'AltHotkey' : 'Z',
                  'FormLabel' : "Ziehwarnung Monat"
              },
    'zeigeWarnungHome' : {  // Auswahl, ob eine Meldung im Managerbuero erscheint, wenn Talente gezogen werden sollten
                  'Name'      : "showWarningHome",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung B\xFCro ein",
                  'Hotkey'    : 'z',
                  'AltLabel'  : "Ziehwarnung B\xFCro aus",
                  'AltHotkey' : 'z',
                  'FormLabel' : "Ziehwarnung B\xFCro"
              },
    'zeigeWarnungDialog' : {  // Auswahl, ob die Meldung im Managerbuero als Dialog erscheinen soll
                  'Name'      : "showWarningDialog",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : false,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung B\xFCro als Dialog",
                  'Hotkey'    : 'z',
                  'AltLabel'  : "Ziehwarnung B\xFCro als Textmeldung",
                  'AltHotkey' : 'z',
                  'FormLabel' : "Ziehwarnung B\xFCro Dialog"
              },
    'zeigeWarnungAufstieg' : {  // Auswahl, ob eine Warnung in der Uebersicht erscheint, wenn Talente nach Aufstieg nicht mehr gezogen werden koennen
                  'Name'      : "showWarningAufstieg",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung Aufstieg ein",
                  'Hotkey'    : 'ä',
                  'AltLabel'  : "Ziehwarnung Aufstieg aus",
                  'AltHotkey' : 'ä',
                  'FormLabel' : "Ziehwarnung Aufstieg"
              },
    'zeigeWarnungLegende' : {  // Auswahl, ob eine extra Meldung in Teamuebersicht erscheint, die dort als Legende dient
                  'Name'      : "showWarningLegende",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung Legende ein",
                  'Hotkey'    : 'L',
                  'AltLabel'  : "Ziehwarnung Legende aus",
                  'AltHotkey' : 'L',
                  'FormLabel' : "Ziehwarnung Legende"
               },
               },
     'zeigeBalken' : {    // Spaltenauswahl fuer den Qualitaetsbalken des Talents (true = anzeigen, false = nicht anzeigen)
     'zeigeBalken' : {    // Spaltenauswahl fuer den Qualitaetsbalken des Talents (true = anzeigen, false = nicht anzeigen)
Zeile 224: Zeile 136:
                   'FormLabel' : "Balken Qualit\xE4t"
                   'FormLabel' : "Balken Qualit\xE4t"
               },
               },
     'absBalken' : {       // Spaltenauswahl fuer den Guetebalken des Talents absolut statt nach Foerderung (true = absolut, false = relativ nach Foerderung)
     'absBalken' : {     // Spaltenauswahl fuer den Guetebalken des Talents absolut statt nach Foerderung (true = absolut, false = relativ nach Foerderung)
                   'Name'      : "absBar",
                   'Name'      : "absBar",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 585: Zeile 497:
                   'FreeValue' : true,
                   'FreeValue' : true,
                   'SelValue'  : false,
                   'SelValue'  : false,
                   'Choice'    : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ],
                   'Choice'    : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ],
                   'Default'  : 16,
                   'Default'  : 12,
                   'Action'    : __OPTACTION.NXT,
                   'Action'    : __OPTACTION.NXT,
                   'Label'    : "Saison: $",
                   'Label'    : "Saison: $",
Zeile 732: Zeile 644:
                   'Label'    : "Aufwertungen:"
                   'Label'    : "Aufwertungen:"
               },
               },
     'ziehAnz' : {        // Datenspeicher fuer Anzahl zu ziehender Jugendspieler bis zur naechsten Abrechnung
     'zatAges' : {        // Datenspeicher fuer (gebrochene) Alter der Jugendspieler
                   'Name'      : "drawCounts",
                   'Name'      : "zatAges",
                   'Type'      : __OPTTYPES.SD,
                   'Type'      : __OPTTYPES.SD,
                   'Hidden'    : true,
                   'Hidden'    : true,
                   'Serial'    : true,
                   'Serial'    : true,
                   'AutoReset' : false,
                   'AutoReset' : true,
                   'Permanent' : true,
                   'Permanent' : true,
                   'Default'  : [],
                   'Default'  : [],
                   'Submit'    : undefined,
                   'Submit'    : undefined,
                   'Cols'      : 25,
                   'Cols'      : 36,
                   'Rows'      : 1,
                   'Rows'      : 2,
                   'Replace'  : null,
                   'Replace'  : null,
                   'Space'    : 0,
                   'Space'    : 0,
                   'Label'    : "Zu ziehen:"
                   'Label'    : "ZAT-Alter:"
               },
               },
    'ziehAnzAufstieg' : { // Datenspeicher fuer Anzahl zu ziehender Jugendspieler bis zur naechsten Abrechnung im Falle eines Aufstiegs
     'trainiert' : {      // Datenspeicher fuer Trainingsquoten der Jugendspieler
                  'Name'      : "drawCountsAufstieg",
                   'Name'      : "numProgresses",
                  'Type'      : __OPTTYPES.MC,
                   'Type'      : __OPTTYPES.SD,
                  'ValType'  : 'Number',
                  'Hidden'    : true,
                  'AutoReset' : false,
                  'Permanent' : true,
                  'FreeValue' : true,
                  'SelValue'  : false,
                  'Choice'    : [ 0, 1, 2, 3, 4, 5 ],
                  'Default'  : 0,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Zu ziehen bei Aufstieg: $",
                  'Hotkey'    : 'z',
                  'FormLabel' : "Zu ziehen bei Aufstieg:|$"
              },
    'zatAges' : {        // Datenspeicher fuer (gebrochene) Alter der Jugendspieler
                  'Name'      : "zatAges",
                  'Type'      : __OPTTYPES.SD,
                  'Hidden'    : true,
                  'Serial'    : true,
                  'AutoReset' : true,
                  'Permanent' : true,
                  'Default'  : [],
                  'Submit'    : undefined,
                  'Cols'      : 36,
                  'Rows'      : 2,
                  'Replace'  : null,
                  'Space'    : 0,
                  'Label'    : "ZAT-Alter:"
              },
     'trainiert' : {      // Datenspeicher fuer Trainingsquoten der Jugendspieler
                   'Name'      : "numProgresses",
                   'Type'      : __OPTTYPES.SD,
                   'Hidden'    : true,
                   'Hidden'    : true,
                   'Serial'    : true,
                   'Serial'    : true,
Zeile 3.952: Zeile 3.833:
// Optionen mit Daten, die ZAT- und Team-bezogen gemerkt werden...
// Optionen mit Daten, die ZAT- und Team-bezogen gemerkt werden...
__TEAMCLASS.optSelect = {
__TEAMCLASS.optSelect = {
                             'datenZat'       : true,
                             'datenZat'     : true,
                             'oldDatenZat'     : true,
                             'oldDatenZat' : true,
                             'fingerprints'   : true,
                             'fingerprints' : true,
                             'birthdays'       : true,
                             'birthdays'   : true,
                             'tClasses'       : true,
                             'tClasses'     : true,
                             'progresses'     : true,
                             'progresses'   : true,
                            'ziehAnz'        : true,
                             'zatAges'     : true,
                            'ziehAnzAufstieg' : true,
                             'trainiert'   : true,
                             'zatAges'         : true,
                             'positions'   : true,
                             'trainiert'       : true,
                             'skills'       : true,
                             'positions'       : true,
                             'foerderung'   : true
                             'skills'         : true,
                             'foerderung'     : true
                         };
                         };


Zeile 4.034: Zeile 3.913:


// Erschafft die Spieler-Objekte und fuellt sie mit Werten
// Erschafft die Spieler-Objekte und fuellt sie mit Werten
// playerRows: Array von Zeilen mit Array cells (Spielertabelle)
// reloadData: true = Teamuebersicht, false = Spielereinzelwerte
// optSet: Gesetzte Optionen (und Config)
function init(playerRows, optSet, colIdx, offsetUpper = 1, offsetLower = 0, reloadData = false) {
// colIdx: Liste von Spaltenindices der gesuchten Werte
     storePlayerDataFromHTML(playerRows, optSet, colIdx, offsetUpper, offsetLower, reloadData);
// offsetUpper: Ignorierte Zeilen oberhalb der Daten
// offsetLower: Ignorierte Zeilen unterhalb der Daten
// page: 1: Teamuebersicht, 2: Spielereinzelwerte, 3: Opt. Skill, 4: Optionen, Default: 0
function init(playerRows, optSet, colIdx, offsetUpper = 1, offsetLower = 0, page = 0) {
     storePlayerDataFromHTML(playerRows, optSet, colIdx, offsetUpper, offsetLower, page);


     const __SAISON = getOptValue(optSet.saison);
     const __SAISON = getOptValue(optSet.saison);
Zeile 4.047: Zeile 3.921:
     const __GEALTERT = ((__AKTZAT >= 72) ? (getIntFromHTML(playerRows[playerRows.length - offsetLower - 1].cells, colIdx.Age) < 13) : false);
     const __GEALTERT = ((__AKTZAT >= 72) ? (getIntFromHTML(playerRows[playerRows.length - offsetLower - 1].cells, colIdx.Age) < 13) : false);
     const __CURRZAT = (__GEALTERT ? 0 : __AKTZAT);
     const __CURRZAT = (__GEALTERT ? 0 : __AKTZAT);
    const __LGNR = __TEAMCLASS.team.LgNr;
    const __KLASSE = (__LGNR > 1) ? (__LGNR > 3) ? 3 : 2 : 1;
     const __DONATION = getOptValue(optSet.foerderung);
     const __DONATION = getOptValue(optSet.foerderung);
     const __BIRTHDAYS = getOptValue(optSet.birthdays, []);
     const __BIRTHDAYS = getOptValue(optSet.birthdays, []);
Zeile 4.057: Zeile 3.929:
     const __POSITIONS = getOptValue(optSet.positions, []);
     const __POSITIONS = getOptValue(optSet.positions, []);
     const __SKILLS = getOptValue(optSet.skills, []);
     const __SKILLS = getOptValue(optSet.skills, []);
    const __ISSKILLPAGE = (page === 2);
     const __BASEDATA = [ __BIRTHDAYS, __TCLASSES, __PROGRESSES ];  // fuer initPlayer
     const __BASEDATA = [ __BIRTHDAYS, __TCLASSES, __PROGRESSES ];  // fuer initPlayer
     const __DATA = (__ISSKILLPAGE ? [ __SKILLS, __BASEDATA ] : [ __BASEDATA, __SKILLS ]);  // fuer initPlayer: [0] = von HTML-Seite, [1] = aus gespeicherten Daten
     const __DATA = (reloadData ? [ __BASEDATA, __SKILLS ] : [ __SKILLS, __BASEDATA ]);  // fuer initPlayer: [0] = von HTML-Seite, [1] = aus gespeicherten Daten
     const __IDMAP = getPlayerIdMap(optSet);
     const __IDMAP = getPlayerIdMap(optSet);
     const __CATIDS = __IDMAP.catIds;
     const __CATIDS = __IDMAP.catIds;
Zeile 4.073: Zeile 3.944:
             const __AGE = getIntFromHTML(__CELLS, colIdx.Age);
             const __AGE = getIntFromHTML(__CELLS, colIdx.Age);
             const __ISGOALIE = isGoalieFromHTML(__CELLS, colIdx.Age);
             const __ISGOALIE = isGoalieFromHTML(__CELLS, colIdx.Age);
            const __AKTION = getElementFromHTML(__CELLS, colIdx.Akt);
             const __NEWPLAYER = new PlayerRecord(__LAND, __AGE, __ISGOALIE, __SAISON, __CURRZAT, __DONATION);
             const __NEWPLAYER = new PlayerRecord(__LAND, __AGE, __ISGOALIE, __SAISON, __CURRZAT, __DONATION);


             __NEWPLAYER.initPlayer(__DATA[0], j, __ISSKILLPAGE);
             __NEWPLAYER.initPlayer(__DATA[0], j, ! reloadData);


             const __IDX = selectPlayerIndex(__NEWPLAYER, j, __CATIDS);
             const __IDX = selectPlayerIndex(__NEWPLAYER, j, __CATIDS);


             __NEWPLAYER.initPlayer(__DATA[1], __IDX, ! __ISSKILLPAGE);
             __NEWPLAYER.initPlayer(__DATA[1], __IDX, reloadData);


             __NEWPLAYER.prognoseSkills();
             __NEWPLAYER.prognoseSkills();


             if (! __ISSKILLPAGE) {
             if (reloadData) {
                 __NEWPLAYER.setZusatz(__ZATAGES[__IDX], __TRAINIERT[__IDX], __POSITIONS[__IDX]);
                 __NEWPLAYER.setZusatz(__ZATAGES[__IDX], __TRAINIERT[__IDX], __POSITIONS[__IDX]);
             }
             }
            __NEWPLAYER.createWarnDraw(__AKTION, __KLASSE);


             __PLAYERS[j++] = __NEWPLAYER;
             __PLAYERS[j++] = __NEWPLAYER;
Zeile 4.095: Zeile 3.962:
     }
     }


     if (__ISSKILLPAGE) {
     if (reloadData) {
        setPlayerData(__PLAYERS, optSet);
    } else {
         calcPlayerData(__PLAYERS, optSet);
         calcPlayerData(__PLAYERS, optSet);
    } else {
        setPlayerData(__PLAYERS, optSet);
     }
     }


Zeile 4.136: Zeile 4.003:


// Berechnet die Identifikations-IDs (Fingerprints) der Spieler neu und speichert diese
// Berechnet die Identifikations-IDs (Fingerprints) der Spieler neu und speichert diese
// players: Array von PlayerRecord mit den Spielerdaten
// optSet: Gesetzte Optionen (und Config)
function storePlayerIds(players, optSet) {
function storePlayerIds(players, optSet) {
     const __FINGERPRINTS = [];
     const __FINGERPRINTS = [];
Zeile 4.153: Zeile 4.018:


// Sucht fuer den Spieler den Eintrag aus catIds heraus und gibt den (geloeschten) Index zurueck
// Sucht fuer den Spieler den Eintrag aus catIds heraus und gibt den (geloeschten) Index zurueck
// player: PlayerRecord mit den Daten eines Spielers
// index: Position des Spielers im neuen Array von Spielerdaten
// catIds: PlayerIdMap zum Finden des Spielers ueber die Spielerdaten
// return Original-Index der Daten dieses Spielers im Array von Spielerdaten
function selectPlayerIndex(player, index, catIds) {
function selectPlayerIndex(player, index, catIds) {
     const __MYCAT = player.getCat();
     const __MYCAT = player.getCat();
Zeile 4.172: Zeile 4.033:


// Speichtert die abgeleiteten Werte in den Spieler-Objekten
// Speichtert die abgeleiteten Werte in den Spieler-Objekten
// players: Array von PlayerRecord mit den Spielerdaten
// optSet: Gesetzte Optionen (und Config)
function setPlayerData(players, optSet) {
function setPlayerData(players, optSet) {
    const __ZIEHANZAHL = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
    let ziehAnzAufstieg = 0;
     const __ZATAGES = [];
     const __ZATAGES = [];
     const __TRAINIERT = [];
     const __TRAINIERT = [];
Zeile 4.185: Zeile 4.042:


         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
            const __INDEX = players[i].calcZiehIndex();  // Lfd. Nummer des Abrechnungsmonats (0-basiert)
             __ZATAGES[i]   = __ZUSATZ.zatAge;
 
            if ((__INDEX >= 0) && (__INDEX < __ZIEHANZAHL.length)) {
                __ZIEHANZAHL[__INDEX]++;
            }
 
             __ZATAGES[i] = __ZUSATZ.zatAge;
        }
        if (players[i].isZiehAufstieg()) {
            ziehAnzAufstieg++;
         }
         }
         __TRAINIERT[i] = __ZUSATZ.trainiert;
         __TRAINIERT[i] = __ZUSATZ.trainiert;
         __POSITIONS[i] = __ZUSATZ.bestPos;
         __POSITIONS[i] = __ZUSATZ.bestPos;
     }
     }


    setOpt(optSet.ziehAnz, __ZIEHANZAHL, false);
    setOpt(optSet.ziehAnzAufstieg, ziehAnzAufstieg, false);
     setOpt(optSet.zatAges, __ZATAGES, false);
     setOpt(optSet.zatAges, __ZATAGES, false);
     setOpt(optSet.trainiert, __TRAINIERT, false);
     setOpt(optSet.trainiert, __TRAINIERT, false);
Zeile 4.208: Zeile 4.054:


// Berechnet die abgeleiteten Werte in den Spieler-Objekten neu und speichert diese
// Berechnet die abgeleiteten Werte in den Spieler-Objekten neu und speichert diese
// players: Array von PlayerRecord mit den Spielerdaten
// optSet: Gesetzte Optionen (und Config)
function calcPlayerData(players, optSet) {
function calcPlayerData(players, optSet) {
     const __ZATAGES = [];
     const __ZATAGES = [];
Zeile 4.219: Zeile 4.063:


         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
             __ZATAGES[i] = __ZUSATZ.zatAge;
             __ZATAGES[i]   = __ZUSATZ.zatAge;
         }
         }
         __TRAINIERT[i] = __ZUSATZ.trainiert;
         __TRAINIERT[i] = __ZUSATZ.trainiert;
         __POSITIONS[i] = __ZUSATZ.bestPos;
         __POSITIONS[i] = __ZUSATZ.bestPos;
     }
     }


Zeile 4.230: Zeile 4.074:
}
}


// Ermittelt die fuer diese Seite relevanten Werte in den Spieler-Objekten aus den Daten der Seite und speichert diese
// Ermittelt die Werte in den Spieler-Objekten aus den Daten der Seite und speichert diese
// playerRows: Array von Zeilen mit Array cells (Spielertabelle)
// reloadData: true = Teamuebersicht, false = Spielereinzelwerte
// optSet: Gesetzte Optionen (und Config)
function storePlayerDataFromHTML(playerRows, optSet, colIdx, offsetUpper = 1, offsetLower = 0, reloadData = false) {
// colIdx: Liste von Spaltenindices der gesuchten Werte
     if (reloadData) {
// offsetUpper: Ignorierte Zeilen oberhalb der Daten
        const __BIRTHDAYS = [];
// offsetLower: Ignorierte Zeilen unterhalb der Daten
        const __TCLASSES = [];
// page: 1: Teamuebersicht, 2: Spielereinzelwerte, 3: Opt. Skill, 4: Optionen, Default: 0
        const __PROGRESSES = [];
function storePlayerDataFromHTML(playerRows, optSet, colIdx, offsetUpper = 1, offsetLower = 0, page = 0) {
 
     const __COLDEFS = [ { }, {
        for (let i = offsetUpper, j = 0; i < playerRows.length - offsetLower; i++) {
                                'birthdays'  : { 'name' : 'birthdays', 'getFun' : getIntFromHTML, 'params' : [ colIdx.Geb ] },
            const __CELLS = playerRows[i].cells;
                                'tClasses'  : { 'name' : 'tClasses', 'getFun' : getTalentFromHTML, 'params' : [ colIdx.Tal ] },
                                'progresses' : { 'name' : 'progresses', 'getFun' : getAufwertFromHTML, 'params' : [ colIdx.Auf, getOptValue(optSet.shortAufw, true) ] }
                            }, {
                                'skills'    : { 'name' : 'skills', 'getFun' : getSkillsFromHTML, 'params' : [ colIdx ]}
                            } ][getValueIn(page, 1, 2, 0)];


    return storePlayerDataColsFromHTML(playerRows, optSet, __COLDEFS, offsetUpper, offsetLower);
            if (__CELLS.length > 1) {
}
                __BIRTHDAYS[j] = getIntFromHTML(__CELLS, colIdx.Geb);
                __TCLASSES[j] = getTalentFromHTML(__CELLS, colIdx.Tal);
                __PROGRESSES[j] = getAufwertFromHTML(__CELLS, colIdx.Auf, getOptValue(optSet.shortAufw, true));
                j++;
            }
        }
        setOpt(optSet.birthdays, __BIRTHDAYS, false);
        setOpt(optSet.tClasses, __TCLASSES, false);
        setOpt(optSet.progresses, __PROGRESSES, false);
    } else {
        const __SKILLS = [];


// Ermittelt bestimmte Werte in den Spieler-Objekten aus den Daten der Seite und speichert diese
        for (let i = offsetUpper, j = 0; i < playerRows.length - offsetLower; i++) {
// playerRows: Array von Zeilen mit Array cells (Spielertabelle)
            const __CELLS = playerRows[i].cells;
// optSet: Gesetzte Optionen (und Config)
// colDefs: Informationen zu ausgewaehlten Datenspalten
// offsetUpper: Ignorierte Zeilen oberhalb der Daten
// offsetLower: Ignorierte Zeilen unterhalb der Daten
function storePlayerDataColsFromHTML(playerRows, optSet, colDefs, offsetUpper = 1, offsetLower = 0) {
    const __DATA = { };


    for (let key in colDefs) {
            if (__CELLS.length > 1) {
        __DATA[key] = [];
                __SKILLS[j++] = getSkillsFromHTML(__CELLS, colIdx);
            }
        }
        setOpt(optSet.skills, __SKILLS, false);
     }
     }
}


    for (let i = offsetUpper, j = 0; i < playerRows.length - offsetLower; i++) {
// Trennt die Gruppen (z.B. Jahrgaenge) mit Linien
        const __CELLS = playerRows[i].cells;
 
        if (__CELLS.length > 1) {
            for (let key in colDefs) {
                const __COLDEF = colDefs[key];
 
                __DATA[key][j] = __COLDEF.getFun(__CELLS, ...__COLDEF.params);
            }
            j++;
        }
    }
 
    for (let key in colDefs) {
        const __COLDEF = colDefs[key];
 
        __LOG[7]('Schreibe ' + __COLDEF.name + ': ' + __DATA[key]);
 
        setOpt(optSet[__COLDEF.name], __DATA[key], false);
    }
}
 
// Trennt die Gruppen (z.B. Jahrgaenge) mit Linien
function separateGroups(rows, borderString, colIdxSort = 0, offsetUpper = 1, offsetLower = 0, offsetLeft = -1, offsetRight = 0, formatFun = sameValue) {
function separateGroups(rows, borderString, colIdxSort = 0, offsetUpper = 1, offsetLower = 0, offsetLeft = -1, offsetRight = 0, formatFun = sameValue) {
     if (offsetLeft < 0) {
     if (offsetLeft < 0) {
Zeile 4.290: Zeile 4.115:
     }
     }


     for (let i = offsetUpper, newVal, oldVal = formatFun((rows[i].cells[colIdxSort] || { }).textContent); i < rows.length - offsetLower - 1; i++, oldVal = newVal) {
     for (let i = offsetUpper, newVal, oldVal = formatFun(rows[i].cells[colIdxSort].textContent); i < rows.length - offsetLower - 1; i++, oldVal = newVal) {
         newVal = formatFun((rows[i + 1].cells[colIdxSort] || { }).textContent);
         newVal = formatFun(rows[i + 1].cells[colIdxSort].textContent);
         if (newVal !== oldVal) {
         if (newVal !== oldVal) {
             for (let j = offsetLeft; j < rows[i].cells.length - offsetRight; j++) {
             for (let j = offsetLeft; j < rows[i].cells.length - offsetRight; j++) {
Zeile 4.322: Zeile 4.147:


     this.colIdx = colIdx;
     this.colIdx = colIdx;
    this.saison = getOptValue(optSet.saison);
    this.gt = getOptValue(optSet.zeigeJahrgang);
    this.gtUxx = getOptValue(optSet.zeigeUxx);


     this.fpId = (__BIRTHDAYS && __TCLASSES && __POSITIONS && getValue(__SHOWCOL.zeigeId, __SHOWALL) && getOptValue(optSet.zeigeId));
     this.fpId = (__BIRTHDAYS && __TCLASSES && __POSITIONS && getValue(__SHOWCOL.zeigeId, __SHOWALL) && getOptValue(optSet.zeigeId));
    this.warn = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnung, __SHOWALL) && getOptValue(optSet.zeigeWarnung));
    this.warnMonth = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungMonat, __SHOWALL) && getOptValue(optSet.zeigeWarnungMonat));
    this.warnHome = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungHome, __SHOWALL) && getOptValue(optSet.zeigeWarnungHome));
    this.warnDialog = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungDialog, __SHOWALL) && getOptValue(optSet.zeigeWarnungDialog));
    this.warnAufstieg = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungAufstieg, __SHOWALL) && getOptValue(optSet.zeigeWarnungAufstieg));
    this.warnLegende = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungLegende, __SHOWALL) && getOptValue(optSet.zeigeWarnungLegende));
     this.bar = (__PROJECTION && getValue(__SHOWCOL.zeigeBalken, __SHOWALL) && getOptValue(optSet.zeigeBalken));
     this.bar = (__PROJECTION && getValue(__SHOWCOL.zeigeBalken, __SHOWALL) && getOptValue(optSet.zeigeBalken));
     this.barAbs = getOptValue(optSet.absBalken);
     this.barAbs = getOptValue(optSet.absBalken);
Zeile 4.515: Zeile 4.330:
                           },  // Ende addTitles()
                           },  // Ende addTitles()
         'addValues'      : function(player, playerRow, color = "#FFFFFF") {
         'addValues'      : function(player, playerRow, color = "#FFFFFF") {
                              // Warnlevel des Spielers anpassen...
                              const __WARNDRAW = player.warnDraw || player.warnDrawAufstieg || __NOWARNDRAW;
                              __WARNDRAW.setWarn(this.warn, this.warnMonth, this.warnAufstieg);
                               const __IDXPRI = getIdxPriSkills(player.getPos());
                               const __IDXPRI = getIdxPriSkills(player.getPos());
                               const __COLOR = __WARNDRAW.getColor(player.isGoalie ? getColor('TOR') : color); // Angepasst an Ziehwarnung
                              const __COLALERT = getColor('STU');  // rot
                               const __COLOR = ((player.zatLeft < 1) ? __COLALERT : player.isGoalie ? getColor('TOR') : color);
                               const __POS1COLOR = getColor((player.getPosPercent() > 99.99) ? 'LEI' : player.getPos());
                               const __POS1COLOR = getColor((player.getPosPercent() > 99.99) ? 'LEI' : player.getPos());
                               const __OSBLAU = getColor("");
                               const __OSBLAU = getColor("");
Zeile 4.560: Zeile 4.372:
                                   this.addAndFillCell(playerRow, player.getAge(), __COLOR, null, 2);
                                   this.addAndFillCell(playerRow, player.getAge(), __COLOR, null, 2);
                               }
                               }
                               if (__WARNDRAW.monthDraw()) {  // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
                               if (player.zatLeft < 6) {  // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
                                   formatCell(playerRow.cells[this.colIdx.Age], true, __WARNDRAW.colAlert, null, 1.0);
                                   formatCell(playerRow.cells[this.colIdx.Age], true, __COLALERT, null, 1.0);
                               }
                               }
                               if (this.fix) {
                               if (this.fix) {
Zeile 4.611: Zeile 4.423:
                               }
                               }


                               // Einzelwerte mit Ende 18
                               // Werte mit Ende 18
                               if (this.colIdx.Einz) {
                               if (this.substSkills) {
                                  if (this.substSkills) {
                                  convertArrayFromHTML(playerRow.cells, this.colIdx.Einz, player.skillsEnd, function(value, cell, unused, index) {
                                      convertArrayFromHTML(playerRow.cells, this.colIdx.Einz, player.skillsEnd, function(value, cell, unused, index) {
                                                                                                                if (~ __IDXPRI.indexOf(index)) {
                                                                                                                    formatCell(cell, true, __OSBLAU, __POS1COLOR, 1.0);
                                                                                                                }
                                                                                                                return value;
                                                                                                            });
                              } else if (this.colIdx.Einz) {
                                  convertArrayFromHTML(playerRow.cells, this.colIdx.Einz, player.skills.length, function(value, cell, unused, index) {
                                                                                                                     if (~ __IDXPRI.indexOf(index)) {
                                                                                                                     if (~ __IDXPRI.indexOf(index)) {
                                                                                                                         formatCell(cell, true, __OSBLAU, __POS1COLOR, 1.0);
                                                                                                                         formatCell(cell, true, __POS1COLOR, null, 1.0);
                                                                                                                     }
                                                                                                                     }
                                                                                                                     return value;
                                                                                                                     return value;
                                                                                                                 });
                                                                                                                 });
                                  } else {
                                      convertArrayFromHTML(playerRow.cells, this.colIdx.Einz, player.skills.length, function(value, cell, unused, index) {
                                                                                                                        if (~ __IDXPRI.indexOf(index)) {
                                                                                                                            formatCell(cell, true, __POS1COLOR, null, 1.0);
                                                                                                                        }
                                                                                                                        return value;
                                                                                                                    });
                                  }
                               }
                               }
                               if (this.trE) {
                               if (this.trE) {
Zeile 4.670: Zeile 4.480:
                                   }
                                   }
                               }
                               }
                           }, // Ende addValues(player, playerRow)
                           }  // Ende addValues(player, playerRow)
        'setGroupTitle'  : function(tableRow) {
                              if (this.gtUxx) {
                                  const __CELL = tableRow.cells[0];
                                  const __SAI = __CELL.innerHTML.match(/Saison (\d+)/)[1];
                                  const __JG = 13 + this.saison - __SAI;
 
                                  __CELL.innerHTML = __CELL.innerHTML.replace('Jahrgang', 'U' + __JG + ' - $&');
                              }
 
                              tableRow.style.display = (this.gt ? '' : 'none');
                          }  // Ende setGroupTitle(tableRow)
     });
     });


Zeile 4.723: Zeile 4.522:
     // this.trainiert: Anzahl der erfolgreichen Trainingspunkte
     // this.trainiert: Anzahl der erfolgreichen Trainingspunkte
     // indirekt this.zatAge und this.bestPos
     // indirekt this.zatAge und this.bestPos
    // in this.createWarnDraw() definiert:
    // this.warnDraw: Behandlung von Warnungen Ende 18
    // this.warnDrawAufstieg: Behandlung von Warnungen bei Aufstieg


     // in this.getPos() definiert:
     // in this.getPos() definiert:
Zeile 4.768: Zeile 4.563:
                                       return result;
                                       return result;
                                   },  // Ende this.toString()
                                   },  // Ende this.toString()
         'initPlayer'            : function(data, index, isSkillData = false) {  // isSkillData: true = Skilldaten, false = Basiswerte (Geb., Talent, Aufwertungen) oder keine
         'initPlayer'            : function(data, index, skillData = false) {  // skillData: true = Skilldaten, false = Basiswerte (Geb., Talent, Aufwertungen)
                                       if (data !== undefined) {
                                       if (data !== undefined) {
                                           if (isSkillData) {
                                           if (skillData) {
                                               this.setSkills(data[index]);
                                               this.setSkills(data[index]);
                                           } else if (data.length >= 2){
                                           } else {
                                               this.setGeb(data[0][index]);
                                               this.setGeb(data[0][index]);
                                               this.talent = data[1][index];
                                               this.talent = data[1][index];
                                               this.aufwert = data[2][index];
                                               this.aufwert = data[2][index];
                                          } else {
                                              // keine Daten
                                           }
                                           }
                                       }
                                       }
                                   },  // Ende this.initPlayer()
                                   },  // Ende this.initPlayer()
        'createWarnDraw'        : function(ziehmich = null, klasse = 1) {  // ziehmich: input Element zum Ziehen; klasse: Spielklasse 1, 2, 3
                                      // Objekte fuer die Verwaltung der Ziehwarnungen...
                                      this.warnDraw = undefined;
                                      this.warnDrawAufstieg = undefined;
                                      if (ziehmich) {
                                          const __LASTZAT = this.currZAT + this.getZatLeft();
                                          if (__LASTZAT < 72) {  // U19
                                              this.warnDraw = new WarnDrawPlayer(this, getColor('STU'));  // rot
                                              __LOG[4](this.getAge().toFixed(2), "rot");
                                          } else if (__LASTZAT < Math.max(2, klasse) * 72) {  // Rest bis inkl. U18 (Liga 1 und 2) bzw. U17 (Liga 3)
                                              // do nothing
                                          } else if (__LASTZAT < (klasse + 1) * 72) {  // U17/U16 je nach Liga 2/3
                                              this.warnDrawAufstieg = new WarnDrawPlayer(this, getColor('OMI'));  // magenta
                                              this.warnDrawAufstieg.setAufstieg();
                                              __LOG[4](this.getAge().toFixed(2), "magenta");
                                          }
                                      }
                                  },  // Ende this.createWarnDraw()
         'setSkills'            : function(skills) {
         'setSkills'            : function(skills) {
                                       // Berechnet die Opti-Werte, sortiert das Positionsfeld und berechnet die Einzelskills mit Ende 18
                                       // Berechnet die Opti-Werte, sortiert das Positionsfeld und berechnet die Einzelskills mit Ende 18
Zeile 4.887: Zeile 4.661:
                                       if (when === this.__TIME.end) {
                                       if (when === this.__TIME.end) {
                                           return (18 - 12) * 72 - 1;  // (max.) Trainings-ZATs bis Ende 18
                                           return (18 - 12) * 72 - 1;  // (max.) Trainings-ZATs bis Ende 18
                                       } else if (this.zatAge !== undefined) {
                                       } else {
                                           return this.zatAge;
                                           return this.zatAge;
                                      } else {
                                          __LOG[4]("Empty getZatAge()");
                                          return NaN;
                                       }
                                       }
                                   },
                                   },
Zeile 4.904: Zeile 4.674:


                                       return this.zatLeft;
                                       return this.zatLeft;
                                  },
        'calcZiehIndex'        : function() {
                                      //const __RESTZAT = this.getZatAge(this.__TIME.end) - this.getZatAge() + this.currZAT;
                                      //const __INDEX = parseInt(__RESTZAT / 6 + 1) - 1;  // Lfd. Nummer des Abrechnungsmonats (0-basiert)
                                      return (this.warnDraw && this.warnDraw.calcZiehIndex(this.currZAT));
                                  },
        'isZiehAufstieg'        : function() {
                                      return (this.warnDrawAufstieg && this.warnDrawAufstieg.isZiehAufstieg());
                                   },
                                   },
         'getAge'                : function(when = this.__TIME.now) {
         'getAge'                : function(when = this.__TIME.now) {
Zeile 5.130: Zeile 4.891:
     });
     });


// Klasse WarnDrawPlayer *****************************************************************
// Funktionen fuer die HTML-Seite *******************************************************


function WarnDrawPlayer(player, alertColor) {
// Liest eine Zahl aus der Spalte einer Zeile der Tabelle aus (z.B. Alter, Geburtsdatum)
     'use strict';
// cells: Die Zellen einer Zeile
// colIdxInt: Spaltenindex der gesuchten Werte
// return Spalteneintrag als Zahl (-1 fuer "keine Zahl", undefined fuer "nicht gefunden")
function getIntFromHTML(cells, colIdxInt) {
     const __CELL = getValue(cells[colIdxInt], { });
    const __TEXT = __CELL.textContent;


     this.player = player;
     if (__TEXT !== undefined) {
        try {
            const __VALUE = parseInt(__TEXT, 10);


    if (this.player !== undefined) {
            if (! isNaN(__VALUE)) {
        // Default Warnlevel...
                return __VALUE;
        this.setZatLeft(player.getZatLeft());
            }
        this.currZAT = player.currZAT;
         } catch (ex) { }
        this.setWarn(true, true, true);
 
         this.colAlert = alertColor || this.alertColor();
         return -1;
    } else {
        // Kein Warnlevel...
        this.setZatLeft(undefined);
        this.currZAT = undefined;
        this.setWarn(false, false, false);
         this.colAlert = undefined;
     }
     }
    return undefined;
}
}


Class.define(WarnDrawPlayer, Object, {
// Liest eine Dezimalzahl aus der Spalte einer Zeile der Tabelle aus
        '__MONATEBISABR'    : 1,
// cells: Die Zellen einer Zeile
        '__ZATWARNVORLAUF'  : 1,
// colIdxInt: Spaltenindex der gesuchten Werte
        '__ZATMONATVORLAUF' : 6,
// return Spalteneintrag als Dezimalzahl (undefined fuer "keine Zahl" oder "nicht gefunden")
        'setZatLeft'        : function(zatLeft) {
function getFloatFromHTML(cells, colIdxFloat) {
                                  this.zatLeft = zatLeft;
    const __CELL = getValue(cells[colIdxFloat], { });
                              },
     const __TEXT = __CELL.textContent;
        'setWarn'          : function(warn, warnMonth, warnAufstieg) {
                                  this.warn = (this.aufstieg ? warnAufstieg : warn);
                                  this.warnMonth = warnMonth;
                              },
        'alertColor'        : function() {
                                  return getColor('STU');  // rot
                              },
        'getColor'          : function(color) {
                                  return ((this.mustDraw() && this.colAlert) ? this.colAlert : color);
                              },
        'calcZiehIndex'     : function(currZAT) {
                                  const __RESTZAT = this.zatLeft + currZAT;
                                  const __INDEX = parseInt(__RESTZAT / 6 + 1) - this.__MONATEBISABR; // Lfd. Nummer des Abrechnungsmonats (0-basiert)


                                  return __INDEX;
    if (__TEXT !== undefined) {
                              },
         try {
         'isZiehAufstieg'    : function() {
            return parseFloat(__TEXT);
                                  return this.aufstieg;
        } catch (ex) { }
                              },
    }
        'setAufstieg'      : function() {
                                  this.aufstieg = true;


                                  if (this.isZiehAufstieg()) {
    return undefined;
                                      this.setZatLeft(72 - this.currZAT - this.__ZATWARNVORLAUF);
}
                                  }


                                  return this.zatLeft;
// Liest einen String aus der Spalte einer Zeile der Tabelle aus
                              },
// cells: Die Zellen einer Zeile
        'mustDraw'          : function() {
// colIdxStr: Spaltenindex der gesuchten Werte
                                  return ((this.warn || this.warnMonth) && (this.zatLeft < this.__ZATWARNVORLAUF));
// return Spalteneintrag als String ("" fuer "nicht gefunden")
                              },
function getStringFromHTML(cells, colIdxStr) {
        'monthDraw'        : function() {
    const __CELL = getValue(cells[colIdxStr], { });
                                  return (this.mustDraw() || (this.warn && (this.aufstieg || this.warnMonth) && (this.zatLeft < this.__ZATMONATVORLAUF))); // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
     const __TEXT = __CELL.textContent;
                              }
     });


const __NOWARNDRAW = new WarnDrawPlayer(undefined, undefined); // inaktives Objekt
    return getValue(__TEXT.toString(), "");
}


// Klasse WarnDrawMessage *****************************************************************
// Liest die Talentklasse ("wenig", "normal", "hoch") aus der Spalte einer Zeile der Tabelle aus
// cells: Die Zellen einer Zeile
// colIdxStr: Spaltenindex der gesuchten Werte
// return Talent als Zahl (-1=wenig, 0=normal, +1=hoch)
function getTalentFromHTML(cells, colIdxTal) {
    const __TEXT = getStringFromHTML(cells, colIdxTal);


function WarnDrawMessage(optSet, currZAT) {
    return parseInt((__TEXT === 'wenig') ? -1 : (__TEXT === 'hoch') ? +1 : 0, 10);
    'use strict';
}


     this.optSet = optSet;
// Liest die Einzelskills aus der Spalte einer Zeile der Tabelle aus
// cells: Die Zellen einer Zeile
// colIdx: Liste von Spaltenindices der gesuchten Werte mit den Eintraegen
// 'Einz' (erste Spalte) und 'Zus' (Spalte hinter dem letzten Eintrag)
// return Skills als Array von Zahlen
function getSkillsFromHTML(cells, colIdx) {
     const __RESULT = [];


     this.warn = getOptValue(this.optSet.zeigeWarnung, true);
     for (let i = colIdx.Einz; i < colIdx.Zus; i++) {
    this.warnMonth = getOptValue(this.optSet.zeigeWarnungMonat, true);
        __RESULT[i - colIdx.Einz] = getIntFromHTML(cells, i);
    this.warnHome = getOptValue(this.optSet.zeigeWarnungHome, true);
     }
    this.warnDialog = getOptValue(this.optSet.zeigeWarnungDialog, false);
    this.warnAufstieg = getOptValue(this.optSet.zeigeWarnungAufstieg, true);
     this.warnLegende = getOptValue(this.optSet.zeigeWarnungLegende, true);


     this.out = {
     return __RESULT;
                  'supertag' : true,
}
                  'top'      : true,
                  'link'    : true,
                  'label'    : true,
                  'bottom'  : true
              };


    this.setOptionHome();
// Liest aus, ob der Spieler Torwart oder Feldspieler ist
 
// cells: Die Zellen einer Zeile
     this.startMessage(currZAT);
// colIdxClass: Spaltenindex einer fuer TOR eingefaerbten Zelle
// return Angabe, der Spieler Torwart oder Feldspieler ist
function isGoalieFromHTML(cells, colIdxClass) {
     return (cells[colIdxClass].className === 'TOR');
}
}


Class.define(WarnDrawMessage, Object, {
// Liest einen String aus der Spalte einer Zeile der Tabelle aus, nachdem dieser konvertiert wurde
        '__ZATWARNVORLAUF'  : 1,
// cells: Die Zellen einer Zeile
        '__ZATMONATVORLAUF' : 6,
// colIdxStr: Spaltenindex der gesuchten Werte
        'startMessage'      : function(currZAT) {
// convertFun: Funktion, die den Wert konvertiert
                                  this.setZat(currZAT);
// return Spalteneintrag als String ("" fuer "nicht gefunden")
                                  this.createMessage();
function convertStringFromHTML(cells, colIdxStr, convertFun = sameValue) {
                              },
    const __CELL = getValue(cells[colIdxStr], { });
        'setZat'            : function(currZAT) {
    const __TEXT = convertFun(__CELL.textContent, __CELL, colIdxStr, 0);
                                  this.currZAT = currZAT;


                                  if (currZAT === undefined) {
    if (__TEXT !== undefined) {
                                      this.abrZAT = undefined;
        __CELL.innerHTML = __TEXT;
                                      this.rest  = undefined;
     }
                                      this.anzahl = undefined;
                                  } else {
                                      this.configureZat();
                                  }
                              },
        'setOptionHome'     : function() {
                                  this.warnOption = this.hasHome();
                              },
        'setOptionLegende'  : function() {
                                  this.warnOption = this.hasLegende();
                              },
        'configureZat'      : function() {
                                  const __ZIEHANZAHL = getOptValue(this.optSet.ziehAnz, []);
                                  const __INDEX = parseInt(this.currZAT / 6);


                                  this.abrZAT = (__INDEX + 1) * 6;
    return getValue(__TEXT.toString(), "");
                                  this.rest  = 5 - (this.currZAT % 6);
}
                                  this.anzahl = __ZIEHANZAHL[__INDEX];
                              },
        'getTextMessage'    : function() {
                                  return "ZAT " + this.abrZAT + ' ' + ((this.anzahl > 1) ? "m\xFCssen " + this.anzahl : "muss einer") +
                                        " deiner Jugendspieler in das Profiteam \xFCbernommen werden, ansonsten verschwinde" + ((this.anzahl > 1) ? "n sie" : "t er") + '!';
                              },
        'createMessage'    : function() {
                                  this.label = undefined;
                                  this.when = undefined;
                                  this.text = undefined;


                                  if (this.hasHome() || this.hasLegende() || this.hasDialog()) {
// Liest ein Array von String-Werten aus den Spalten ab einer Zeile der Tabelle aus, nachdem diese konvertiert wurden
                                      if (this.anzahl > 0) {
// cells: Die Zellen einer Zeile
                                          this.text = this.getTextMessage();
// colIdxArr: Erster Spaltenindex der gesuchten Werte
// arrOrLength: Entweder ein Datenarray zum Fuellen oder die Anzahl der zu lesenden Werte
// convertFun: Funktion, die die Werte konvertiert
// return Array mit Spalteneintraegen als String ("" fuer "nicht gefunden")
function convertArrayFromHTML(cells, colIdxArr, arrOrLength = 1, convertFun = sameValue) {
    const __ARR = ((typeof arrOrSize === 'number') ? { } : arrOrLength);
    const __LENGTH = getValue(__ARR.length, arrOrLength);
    const __RET = [];


                                          if (this.warnMonth && (this.rest > 0)) {
    for (let index = 0, colIdx = colIdxArr; index < __LENGTH; index++, colIdx++) {
                                              this.label = "Warnung";
         const __CELL = getValue(cells[colIdx], { });
                                              this.when = "Bis zur n\xE4chsten Abrechnung am ";
         const __TEXT = convertFun(getValue(__ARR[index], __CELL.textContent), __CELL, colIdx, index);
                                          } else if ((this.warn || this.warnMonth) && (this.rest === 0)) {
                                              this.label = "LETZTE WARNUNG VOR DER ABRECHNUNG";
                                              this.when = "Bis zum n\xE4chsten ";
                                          }
                                      }
                                  }
                              },
        'hasMessage'        : function() {
                                  return !! this.when;
                              },
         'hasHome'          : function() {
                                  return this.warnHome;
                              },
        'hasLegende'        : function() {
                                  return this.warnLegende;
                              },
        'hasOption'        : function() {
                                  return this.warnOption;
                              },
         'hasDialog'        : function() {
                                  return this.warnDialog;
                              },
        'showMessage'      : function(anchor, tag, appendFind = true) {  // appendFind: true = append, false = insertBefore, "..." search string = insert at find position
                                  let ret = (anchor || { }).innerHTML;


                                  if (this.hasMessage()) {
        if (__TEXT !== undefined) {
                                      if (this.hasOption()) {
            __CELL.innerHTML = __TEXT;
                                          const __OLDHTML = ret;
        }
                                          const __HTML = this.getHTML(tag);


                                          if ((typeof appendFind) === 'string') {
        __RET.push(getValue(__TEXT, "").toString());
                                              const __INDEX = __OLDHTML.indexOf(appendFind);
    }
                                              const __POS = (~ __INDEX) ? __INDEX : __OLDHTML.length;


                                              ret = __OLDHTML.substring(0, __POS) + __HTML + __OLDHTML.substring(__POS);
    return __RET;
                                          } else if (appendFind) {
}
                                              ret = __OLDHTML + __HTML;
                                          } else {
                                              ret = __HTML + __OLDHTML;
                                          }


                                          anchor.innerHTML = ret;
// Konvertiert den Aufwertungstext einer Zelle auf der Jugend-Teamuebersicht
                                      }
// value: Der Inhalt dieser Zeile ("+1 SKI +1 OPT" bzw. "+2 SKI)
                                  }
// cell: Zelle, in der der Text stand (optional)
// return Der konvertierte String ("SKI OPT" bzw. "SKI SKI")
function convertAufwertung(value, cell = undefined) {
    if (value !== undefined) {
        value = value.replace(/\+2 (\w+)/, "$1 $1").replace(/\+1 /g, "");


                                  return ret;
         if (cell) {
                              },
            if (cell.className === 'TOR') {
         'showDialog'        : function(dlgFun) {
                value = convertGoalieSkill(value);
                                  if (this.hasMessage()) {
            }
                                      if (this.hasDialog() && (this.rest === 0)) {
                                          dlgFun(this.label, this.when + this.text);
                                      }
                                  }
                              },
        'tagText'           : function(tag, text) {
                                  return ((tag !== undefined) ? this.getOpeningTag(tag) + text + this.getClosingTag(tag) : text);
                              },
        'tagParagraph'      : function(tag, text) {
                                  return this.tagText(tag, this.tagText(this.getSubTag(tag), text));
                              },
        'getSubTag'        : function(tag) {
                                  return ((tag === 'tr') ? 'td' + this.getColorTD() : ((tag === 'p') ? this.getColorTag() : undefined));
                              },
        'getSuperTag'      : function(tag) {
                                  return ((tag === 'p') ? 'div' : undefined);
                              },
        'getOpeningTag'    : function(tag) {
                                  return '<' + tag + '>';
                              },
        'getClosingTag'    : function(tag) {
                                  const __INDEX1 = (tag ? tag.indexOf(' ') : -1);
                                  const __INDEX2 = (tag ? tag.indexOf('=') : -1);
                                  const __INDEX = ((~ __INDEX1) && (~ __INDEX2)) ? Math.min(__INDEX1, __INDEX2) : Math.max(__INDEX1, __INDEX2);
                                  const __TAGNAME = ((~ __INDEX) ? tag.substring(0, __INDEX) : tag);


                                  return "</" + __TAGNAME + '>';
            cell.align = 'left';
                              },
         }
        'getLink'          : function() {
     }
                                  return './ju.php';
                              },
        'getTopHTML'        : function(tag) {
                                  return this.tagParagraph(tag, "&nbsp;");
                              },
        'getBottomHTML'    : function(tag) {
                                  return this.tagParagraph(tag, "&nbsp;");
                              },
        'getColorTag'      : function() {
                                  return "color='red'";  // rot
                              },
        'getColorTD'        : function() {
                                  return " class='STU'"; // rot
                              },
         'getHTML'          : function(tag = 'p') {
                                  return this.tagParagraph((this.out.supertag ? this.getSuperTag(tag) : undefined), (this.out.top ? this.getTopHTML(tag) : "") +
                                        this.tagParagraph(tag, this.tagText('b', this.tagText((this.out.link ? "a href='" + this.getLink() + "'" : undefined),
                                        (this.out.label ? this.label + ": " : "") + this.when + this.text))) + (this.out.bottom ? this.getBottomHTML(tag) : ""));
                              }
     });


Object.defineProperty(WarnDrawMessage.prototype, 'innerHTML', {
    return value;
        get : function() {
}
                  return this.getHTML('p');
              }
    });


// Klasse WarnDrawMessageAufstieg *****************************************************************
// Konvertiert die allgemeinen Skills in die eines Torwarts
// value: Ein Text, der die Skillnamen enthaelt
// return Der konvertierte String mit Aenderungen (z.B. "FAN" statt "KOB") oder unveraendert
function convertGoalieSkill(value) {
    if (value !== undefined) {
        value = value.replace(/\w+/g, getGoalieSkill);
    }


function WarnDrawMessageAufstieg(optSet, currZAT) {
     return value;
     'use strict';
}


    WarnDrawMessage.call(this, optSet, currZAT);
// Konvertiert einen Aufwertungstext fuer einen Skillnamen in den fuer einen Torwart
// name: Allgemeiner Skillname (abgeleitet von den Feldspielern)
// return Der konvertierte String (z.B. "FAN" statt "KOB") oder unveraendert
function getGoalieSkill(name) {
    const __GOALIESKILLS = {
                              'SCH' : 'ABS',
                              'BAK' : 'STS',
                              'KOB' : 'FAN',
                              'ZWK' : 'STB',
                              'DEC' : 'SPL',
                              'GES' : 'REF'
                          };


     this.out.top = false;  // kein Vorschub vor der Zeile
     return getValue(__GOALIESKILLS[name], name);
 
    this.warn = (this.warn && this.warnAufstieg);  // kann man ausschalten
    this.startMessage(currZAT); // 2. Aufruf (zur Korrektur)
}
}


Class.define(WarnDrawMessageAufstieg, WarnDrawMessage, {
// Liest die Aufwertungen eines Spielers aus und konvertiert je nachdem, ob der Spieler Torwart oder Feldspieler ist
        'configureZat'      : function() {
// cells: Die Zellen einer Zeile
                                  const __ZIEHANZAUFSTIEG = getOptValue(this.optSet.ziehAnzAufstieg, 0);
// colIdxAuf: Spaltenindex der gesuchten Aufwertungen
                                  const __INDEX = parseInt(this.currZAT / 6);
// shortForm: true = abgekuerzt, false = Originalform
// return Konvertierte Aufwertungen (kurze oder lange Form, aber in jedem Fall fuer Torwart konvertiert)
function getAufwertFromHTML(cells, colIdxAuf, shortForm = true) {
    const __ISGOALIE = isGoalieFromHTML(cells, colIdxAuf);


                                  this.abrZAT = (__INDEX + 1) * 6;
    return convertStringFromHTML(cells, colIdxAuf, (shortForm ? convertAufwertung : __ISGOALIE ? convertGoalieSkill : undefined));
                                  this.rest  = 5 - (this.currZAT % 6);
}
                                  this.anzahl = ((this.currZAT + this.__ZATMONATVORLAUF > 72 - this.__ZATWARNVORLAUF) ? __ZIEHANZAUFSTIEG : 0);


                                  this.warnDialog = false;    // kein Dialog fuer Aufstiegswarnung
// Identitaetsfunktion. Konvertiert nichts, sondern liefert einfach den Wert zurueck
                                  this.warnMonth = this.warn;  // nur im letzten Monat der Saison!
// value: Der uebergebene Wert
                              },
// return Derselbe Wert
        'getTextMessage'    : function() {
function sameValue(value) {
                                  return "ZAT " + this.abrZAT + " ist im Falle eines Aufstiegs f\xFCr " + ((this.anzahl > 1) ? "" + this.anzahl : "einen") +
    return value;
                                        " deiner Jugendspieler m\xF6glicherweise die letzte Chance, " + ((this.anzahl > 1) ? " diese noch vor ihrem" : "ihn noch vor seinem") +
}
                                        " Geburtstag in der n\xE4chsten Saison in das Profiteam zu \xFCbernehmen!";
                              },
        'getColorTag'      : function() {
                                  return "color='magenta'";  // magenta
                              },
        'getColorTD'        : function() {
                                  return " class='OMI'"; // magenta
                              }
    });


// Ende Hilfs-Klassen *****************************************************************
// Liefert den ganzzeiligen Anteil einer Zahl zurueck, indem alles hinter einem Punkt abgeschnitten wird
// value: Eine uebergebene Dezimalzahl
// return Der ganzzeilige Anteil dieser Zahl
function floorValue(value, dot = '.') {
    if ((value === 0) || (value && isFinite(value))) {
        const __VALUE = value.toString();
        const __INDEXDOT = (__VALUE ? __VALUE.indexOf(dot) : -1);


// Funktionen fuer die HTML-Seite *******************************************************
        return Number((~ __INDEXDOT) ? __VALUE.substring(0, __INDEXDOT) : __VALUE);
    } else {
        return value;
    }
}


// Liest eine Zahl aus der Spalte einer Zeile der Tabelle aus (z.B. Alter, Geburtsdatum)
// Liefert einen rechtsbuendigen Text zurueck, der links aufgefuellt wird
// cells: Die Zellen einer Zeile
// value: Ein uebergebener Wert
// colIdxInt: Spaltenindex der gesuchten Werte
// size: Zielbreite (clipping fuer < 0: Abschneiden, falls zu lang)
// return Spalteneintrag als Zahl (-1 fuer "keine Zahl", undefined fuer "nicht gefunden")
// char: Zeichen zum Auffuellen
function getIntFromHTML(cells, colIdxInt) {
// return Ein String, der mindestens |size| lang ist (oder genau, falls size < 0, also clipping)
     const __CELL = getValue(cells[colIdxInt], { });
function padLeft(value, size = 4, char = ' ') {
     const __TEXT = __CELL.textContent;
     const __SIZE = Math.abs(size);
    const __CLIP = (size < 0);
     const __VALUE = (value ? value.toString() : "");
    let i = __VALUE.length;
    let str = "";


     if (__TEXT !== undefined) {
     while (i < __SIZE) {
         try {
         str += char;
            const __VALUE = parseInt(__TEXT, 10);
        i += char.length;
    }
    str = ((i > __SIZE) ? str.slice(0, __SIZE - __VALUE.length - 1) : str) + __VALUE;


            if (! isNaN(__VALUE)) {
    return (__CLIP ? str.slice(size) : str);
                return __VALUE;
}
            }
        } catch (ex) { }


         return -1;
// Liefert eine rechtsbuendigen Zahl zurueck, der links (mit Nullen) aufgefuellt wird
// value: Eine uebergebene Zahl
// size: Zielbreite (Default: 2)
// char: Zeichen zum Auffuellen (Default: '0')
// forceClip: Abschneiden erzwingen, falls zu lang?
// return Eine Zahl als String, der mindestens 'size' lang ist (oder genau, falls size < 0, also clipping)
function padNumber(value, size = 2, char = '0') {
    if ((value === 0) || (value && isFinite(value))) {
        return padLeft(value, size, char);
    } else {
         return value;
     }
     }
}


    return undefined;
// Hilfsfunktionen **********************************************************************
}


// Liest eine Dezimalzahl aus der Spalte einer Zeile der Tabelle aus
// Sortiert das Positionsfeld per BubbleSort
// cells: Die Zellen einer Zeile
function sortPositionArray(array) {
// colIdxInt: Spaltenindex der gesuchten Werte
     const __TEMP = [];
// return Spalteneintrag als Dezimalzahl (undefined fuer "keine Zahl" oder "nicht gefunden")
    let transposed = true;
function getFloatFromHTML(cells, colIdxFloat) {
    // TOR soll immer die letzte Position im Feld sein, deshalb - 1
     const __CELL = getValue(cells[colIdxFloat], { });
     let length = array.length - 1;
     const __TEXT = __CELL.textContent;


     if (__TEXT !== undefined) {
     while (transposed && (length > 1)) {
        try {
        transposed = false;
             return parseFloat(__TEXT);
        for (let i = 0; i < length - 1; i++) {
         } catch (ex) { }
            // Vergleich Opti-Werte:
             if (array[i][1] < array[i + 1][1]) {
                // vertauschen
                __TEMP[0] = array[i][0];
                __TEMP[1] = array[i][1];
                array[i][0] = array[i + 1][0];
                array[i][1] = array[i + 1][1];
                array[i + 1][0] = __TEMP[0];
                array[i + 1][1] = __TEMP[1];
                transposed = true;
            }
         }
        length--;
     }
     }
}


     return undefined;
// Fuegt in die uebergebene Zahl Tausender-Trennpunkte ein
}
// Wandelt einen etwaig vorhandenen Dezimalpunkt in ein Komma um
function getNumberString(numberString) {
     if (numberString.lastIndexOf('.') !== -1) {
        // Zahl enthaelt Dezimalpunkt
        const __VORKOMMA = numberString.substring(0, numberString.lastIndexOf('.'));
        const __NACHKOMMA = numberString.substring(numberString.lastIndexOf('.') + 1, numberString.length);
 
        return getNumberString(__VORKOMMA) + ',' + __NACHKOMMA;
    } else {
        // Kein Dezimalpunkt, fuege Tausender-Trennpunkte ein:
        // String umdrehen, nach jedem dritten Zeichen Punkt einfuegen, dann wieder umdrehen:
        const __TEMP = reverseString(numberString);
        let result = "";


// Liest einen String aus der Spalte einer Zeile der Tabelle aus
        for (let i = 0; i < __TEMP.length; i++) {
// cells: Die Zellen einer Zeile
            if ((i > 0) && (i % 3 === 0)) {
// colIdxStr: Spaltenindex der gesuchten Werte
                result += '.';
// return Spalteneintrag als String ("" fuer "nicht gefunden")
            }
function getStringFromHTML(cells, colIdxStr) {
            result += __TEMP.substr(i, 1);
    const __CELL = getValue(cells[colIdxStr], { });
        }
    const __TEXT = __CELL.textContent;


    return getValue(__TEXT.toString(), "");
        return reverseString(result);
    }
}
}


// Liest ein erstes Element aus der Spalte einer Zeile der Tabelle aus
// Dreht den uebergebenen String um
// cells: Die Zellen einer Zeile
function reverseString(string) {
// colIdxStr: Spaltenindex der gesuchten Werte
    let result = "";
// return Spalteneintrag als Element (null fuer "nicht gefunden")
 
function getElementFromHTML(cells, colIdxStr) {
    for (let i = string.length - 1; i >= 0; i--) {
    const __CELL = getValue(cells[colIdxStr], { });
        result += string.substr(i, 1);
    }


     return __CELL.firstElementChild;
     return result;
}
}


// Liest die Talentklasse ("wenig", "normal", "hoch") aus der Spalte einer Zeile der Tabelle aus
// Schaut nach, ob der uebergebene Index zu einem trainierbaren Skill gehoert
// cells: Die Zellen einer Zeile
// Die Indizes gehen von 0 (SCH) bis 16 (EIN)
// colIdxStr: Spaltenindex der gesuchten Werte
function isTrainableSkill(idx) {
// return Talent als Zahl (-1=wenig, 0=normal, +1=hoch)
     const __TRAINABLESKILLS = getIdxTrainableSkills();
function getTalentFromHTML(cells, colIdxTal) {
    const __IDX = parseInt(idx, 10);
     const __TEXT = getStringFromHTML(cells, colIdxTal);
    let result = false;
 
    for (let idxTrainable of __TRAINABLESKILLS) {
        if (__IDX === idxTrainable) {
            result = true;
            break;
        }
    }


     return parseInt((__TEXT === 'wenig') ? -1 : (__TEXT === 'hoch') ? +1 : 0, 10);
     return result;
}
}


// Liest die Einzelskills aus der Spalte einer Zeile der Tabelle aus
// Gibt alle Skill-Namen zurueck
// cells: Die Zellen einer Zeile
function getAllSkillNames(isGoalie = false) {
// colIdx: Liste von Spaltenindices der gesuchten Werte mit den Eintraegen
    if (isGoalie) {
// 'Einz' (erste Spalte) und 'Zus' (Spalte hinter dem letzten Eintrag)
        return [ 'ABS', 'STS', 'FAN', 'STB', 'SPL', 'REF', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
// return Skills als Array von Zahlen
    } else {
function getSkillsFromHTML(cells, colIdx) {
        return [ 'SCH', 'BAK', 'KOB', 'ZWK', 'DEC', 'GES', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
    const __RESULT = [];
    }
}


    for (let i = colIdx.Einz; i < colIdx.Zus; i++) {
// Gibt den Skill-Namen zu einem Index zurueck
        __RESULT[i - colIdx.Einz] = getIntFromHTML(cells, i);
function getSkillName(idx, isGoalie = false) {
    }
    const __ALLNAMES = getAllSkillNames(isGoalie);


     return __RESULT;
     return __ALLNAMES[idx];
}
}


// Liest aus, ob der Spieler Torwart oder Feldspieler ist
// Gibt den Skill-Namen zu einem Index-Array zurueck
// cells: Die Zellen einer Zeile
function getSkillNameArray(idxArr, isGoalie = false) {
// colIdxClass: Spaltenindex einer fuer TOR eingefaerbten Zelle
     return (idxArr ? idxArr.map(function(item) {
// return Angabe, der Spieler Torwart oder Feldspieler ist
                                    return getSkillName(item, isGoalie);
function isGoalieFromHTML(cells, colIdxClass) {
                                }) : idxArr);
     return (cells[colIdxClass].className === 'TOR');
}
}


// Liest einen String aus der Spalte einer Zeile der Tabelle aus, nachdem dieser konvertiert wurde
// Gibt die Indizes aller Skills zurueck
// cells: Die Zellen einer Zeile
function getIdxAllSkills() {
// colIdxStr: Spaltenindex der gesuchten Werte
     return [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
// convertFun: Funktion, die den Wert konvertiert
}
// return Spalteneintrag als String ("" fuer "nicht gefunden")
function convertStringFromHTML(cells, colIdxStr, convertFun = sameValue) {
     const __CELL = getValue(cells[colIdxStr], { });
    const __TEXT = convertFun(__CELL.textContent, __CELL, colIdxStr, 0);


    if (__TEXT !== undefined) {
// Gibt die Indizes der trainierbaren Skills zurueck
        __CELL.innerHTML = __TEXT;
function getIdxTrainableSkills() {
    }
    return [ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 15 ];
}


     return getValue(__TEXT.toString(), "");
// Gibt die Indizes der Fixskills zurueck
function getIdxFixSkills() {
     return [ 6, 7, 12, 13, 14, 16 ];
}
}


// Liest ein Array von String-Werten aus den Spalten ab einer Zeile der Tabelle aus, nachdem diese konvertiert wurden
// Gibt die Indizes der Primaerskills zurueck
// cells: Die Zellen einer Zeile
function getIdxPriSkills(pos) {
// colIdxArr: Erster Spaltenindex der gesuchten Werte
    switch (pos) {
// arrOrLength: Entweder ein Datenarray zum Fuellen oder die Anzahl der zu lesenden Werte
        case 'TOR' : return [ 2, 3, 4, 5 ];
// convertFun: Funktion, die die Werte konvertiert
        case 'ABW' : return [ 2, 3, 4, 15 ];
// return Array mit Spalteneintraegen als String ("" fuer "nicht gefunden")
        case 'DMI' : return [ 1, 4, 9, 11 ];
function convertArrayFromHTML(cells, colIdxArr, arrOrLength = 1, convertFun = sameValue) {
        case 'MIT' : return [ 1, 3, 9, 11 ];
    const __ARR = ((typeof arrOrLength === 'number') ? { } : arrOrLength);
        case 'OMI' : return [ 1, 5, 9, 11 ];
    const __LENGTH = getValue(__ARR.length, arrOrLength);
        case 'STU' : return [ 0, 2, 3, 5 ];
    const __RET = [];
        default :    return [];
    }
}


     for (let index = 0, colIdx = colIdxArr; index < __LENGTH; index++, colIdx++) {
// Gibt die Indizes der (trainierbaren) Sekundaerskills zurueck
         const __CELL = getValue(cells[colIdx], { });
function getIdxSecSkills(pos) {
         const __TEXT = convertFun(getValue(__ARR[index], __CELL.textContent), __CELL, colIdx, index);
     switch (pos) {
        case 'TOR' : return [ 0, 1, 8, 9, 10, 11, 15 ];
        case 'ABW' : return [ 0, 1, 5, 8, 9, 10, 11 ];
        case 'DMI' : return [ 0, 2, 3, 5, 8, 10, 15 ];
         case 'MIT' : return [ 0, 2, 4, 5, 8, 10, 15 ];
        case 'OMI' : return [ 0, 2, 3, 4, 8, 10, 15 ];
         case 'STU' : return [ 1, 4, 8, 9, 10, 11, 15 ];
        default :    return [];
    }
}


        if (__TEXT !== undefined) {
// Gibt die zur Position gehoerige Farbe zurueck
            __CELL.innerHTML = __TEXT;
function getColor(pos) {
         }
    switch (pos) {
 
        case 'TOR' : return "#FFFF00";
         __RET.push(getValue(__TEXT, "").toString());
         case 'ABW' : return "#00FF00";
        case 'DMI' : return "#3366FF";
        case 'MIT' : return "#66FFFF";
         case 'OMI' : return "#FF66FF";
        case 'STU' : return "#FF0000";
        case 'LEI' : return "#FFFFFF";
        case "" :    return "#111166";  // osBlau
        default :    return "";
     }
     }
    return __RET;
}
}


// Konvertiert den Aufwertungstext einer Zelle auf der Jugend-Teamuebersicht
// ==================== Ende Abschnitt genereller Code zur Anzeige der Jugend ====================
// value: Der Inhalt dieser Zeile ("+1 SKI +1 OPT" bzw. "+2 SKI)
// cell: Zelle, in der der Text stand (optional)
// return Der konvertierte String ("SKI OPT" bzw. "SKI SKI")
function convertAufwertung(value, cell = undefined) {
    if (value !== undefined) {
        value = value.replace(/\+2 (\w+)/, "$1 $1").replace(/\+1 /g, "");


        if (cell) {
// ==================== Abschnitt fuer interne IDs auf den Seiten ====================
            if (cell.className === 'TOR') {
                value = convertGoalieSkill(value);
            }


            cell.align = 'left';
const __GAMETYPENRN = {    // "Blind FSS gesucht!"
         }
        'unbekannt'  : -1,
    }
        'reserviert' :  0,
 
        'Frei'      :  0,
     return value;
        'spielfrei'  :  0,
}
        'Friendly'  :  1,
        'Liga'      :  2,
        'LP'         :  3,
        'OSEQ'      :  4,
        'OSE'        :  5,
         'OSCQ'      :  6,
        'OSC'        :  7,
        'Supercup'  : 10
     };


// Konvertiert die allgemeinen Skills in die eines Torwarts
const __GAMETYPEALIASES = {
// value: Ein Text, der die Skillnamen enthaelt
        'unbekannt'  :  "unbekannt",
// return Der konvertierte String mit Aenderungen (z.B. "FAN" statt "KOB") oder unveraendert
        'reserviert' : undefined,
function convertGoalieSkill(value) {
        'Frei'      :  undefined,
    if (value !== undefined) {
        'spielfrei'  :  "",
         value = value.replace(/\w+/g, getGoalieSkill);
        'Friendly'  :  "FSS",
    }
        'Liga'      :  undefined,
        'LP'        :  "Pokal",
        'OSEQ'      :  undefined,
        'OSE'        :  undefined,
        'OSCQ'      :  undefined,
        'OSC'        :  undefined,
         'Supercup'  : "Super"
    };
const __GAMETYPES = reverseMapping(__GAMETYPENRN);


     return value;
const __LIGANRN = {
}
        'unbekannt'  :  0,
        '1. Liga'    :  1,
        '2. Liga A'  :  2,
        '2. Liga B'  :  3,
        '3. Liga A'  :  4,
        '3. Liga B'  :  5,
        '3. Liga C'  :  6,
        '3. Liga D'  :  7
     };
const __LIGATYPES = reverseMapping(__LIGANRN);


// Konvertiert einen Aufwertungstext fuer einen Skillnamen in den fuer einen Torwart
const __LANDNRN = {
// name: Allgemeiner Skillname (abgeleitet von den Feldspielern)
        'unbekannt'              :  0,
// return Der konvertierte String (z.B. "FAN" statt "KOB") oder unveraendert
        'Albanien'              :  45,
function getGoalieSkill(name) {
        'Andorra'                : 95,
    const __GOALIESKILLS = {
        'Armenien'              :  83,
                              'SCH' : 'ABS',
        'Aserbaidschan'          : 104,
                              'BAK' : 'STS',
        'Belgien'                :  12,
                              'KOB' : 'FAN',
        'Bosnien-Herzegowina'    :  66,
                              'ZWK' : 'STB',
        'Bulgarien'              :  42,
                              'DEC' : 'SPL',
        'D\xE4nemark'            :  8,
                              'GES' : 'REF'
        'Deutschland'            :  6,
                          };
        'England'                :  1,
 
        'Estland'                :  57,
    return getValue(__GOALIESKILLS[name], name);
        'Far\xF6er'              :  68,
}
        'Finnland'              :  40,
 
        'Frankreich'            :  32,
// Liest die Aufwertungen eines Spielers aus und konvertiert je nachdem, ob der Spieler Torwart oder Feldspieler ist
        'Georgien'              :  49,
// cells: Die Zellen einer Zeile
        'Griechenland'          :  30,
// colIdxAuf: Spaltenindex der gesuchten Aufwertungen
        'Irland'                :  5,
// shortForm: true = abgekuerzt, false = Originalform
        'Island'                :  29,
// return Konvertierte Aufwertungen (kurze oder lange Form, aber in jedem Fall fuer Torwart konvertiert)
        'Israel'                :  23,
function getAufwertFromHTML(cells, colIdxAuf, shortForm = true) {
        'Italien'                :  10,
    const __ISGOALIE = isGoalieFromHTML(cells, colIdxAuf);
        'Kasachstan'            : 105,
 
        'Kroatien'              :  24,
    return convertStringFromHTML(cells, colIdxAuf, (shortForm ? convertAufwertung : __ISGOALIE ? convertGoalieSkill : undefined));
        'Lettland'               : 97,
}
        'Liechtenstein'         :  92,
        'Litauen'               : 72,
        'Luxemburg'             :  93,
        'Malta'                 : 69,
        'Mazedonien'             :  86,
        'Moldawien'             : 87,
        'Niederlande'           :  11,
        'Nordirland'             :   4,
        'Norwegen'               :  9,
        '\xD6sterreich'         : 14,
        'Polen'                 :  25,
        'Portugal'              :  17,
        'Rum\xE4nien'            :  28,
        'Russland'              :  19,
        'San Marino'            :  98,
        'Schottland'            :  2,
        'Schweden'              :  27,
        'Schweiz'                : 37,
        'Serbien und Montenegro' : 41,
        'Slowakei'              : 70,
        'Slowenien'              :  21,
        'Spanien'                :  13,
        'Tschechien'            :  18,
        'T\xFCrkei'              :  39,
        'Ukraine'                :  20,
        'Ungarn'                :  26,
        'Wales'                  :  3,
        'Weissrussland'          : 71,
        'Zypern'                : 38
    };
const __LAENDER = reverseMapping(__LANDNRN);


// Identitaetsfunktion. Konvertiert nichts, sondern liefert einfach den Wert zurueck
const __TLALAND = {
// value: Der uebergebene Wert
        undefined : 'unbekannt',
// return Derselbe Wert
        'ALB'    : 'Albanien',
function sameValue(value) {
        'AND'    : 'Andorra',
     return value;
        'ARM'    : 'Armenien',
}
        'AZE'    : 'Aserbaidschan',
 
        'BEL'    : 'Belgien',
// Existenzfunktion. Liefert zurueck, ob ein Wert belegt ist
        'BIH'    : 'Bosnien-Herzegowina',
// value: Der uebergebene Wert
        'BUL'    : 'Bulgarien',
// return Angabe ob Wert belegt ist
        'DEN'    : 'D\xE4nemark',
function existValue(value) {
        'GER'    : 'Deutschland',
     return !! value;
        'ENG'    : 'England',
}
        'EST'    : 'Estland',
        'FRO'    : 'Far\xF6er',
        'FIN'    : 'Finnland',
        'FRA'    : 'Frankreich',
        'GEO'    : 'Georgien',
        'GRE'    : 'Griechenland',
        'IRL'    : 'Irland',
        'ISL'    : 'Island',
        'ISR'    : 'Israel',
        'ITA'    : 'Italien',
        'KAZ'    : 'Kasachstan',
        'CRO'    : 'Kroatien',
        'LVA'    : 'Lettland',
        'LIE'    : 'Liechtenstein',
        'LTU'    : 'Litauen',
        'LUX'    : 'Luxemburg',
        'MLT'    : 'Malta',
        'MKD'    : 'Mazedonien',
        'MDA'    : 'Moldawien',
        'NED'    : 'Niederlande',
        'NIR'    : 'Nordirland',
        'NOR'    : 'Norwegen',
        'AUT'    : '\xD6sterreich',
        'POL'    : 'Polen',
        'POR'    : 'Portugal',
        'ROM'    : 'Rum\xE4nien',
        'RUS'    : 'Russland',
        'SMR'    : 'San Marino',
        'SCO'    : 'Schottland',
        'SWE'    : 'Schweden',
        'SUI'    : 'Schweiz',
        'SCG'    : 'Serbien und Montenegro',
        'SVK'    : 'Slowakei',
        'SVN'    : 'Slowenien',
        'ESP'    : 'Spanien',
        'CZE'     : 'Tschechien',
        'TUR'    : 'T\xFCrkei',
        'UKR'    : 'Ukraine',
        'HUN'    : 'Ungarn',
        'WAL'    : 'Wales',
        'BLR'    : 'Weissrussland',
        'CYP'    : 'Zypern'
     };
const __LANDTLAS = reverseMapping(__TLALAND);


// Liefert den ganzzeiligen Anteil einer Zahl zurueck, indem alles hinter einem Punkt abgeschnitten wird
// ==================== Abschnitt fuer Daten des Spielplans ====================
// value: Eine uebergebene Dezimalzahl
// return Der ganzzeilige Anteil dieser Zahl
function floorValue(value, dot = '.') {
    if ((value === 0) || (value && isFinite(value))) {
        const __VALUE = value.toString();
        const __INDEXDOT = (__VALUE ? __VALUE.indexOf(dot) : -1);


        return Number((~ __INDEXDOT) ? __VALUE.substring(0, __INDEXDOT) : __VALUE);
// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
     } else {
// gameType: Name des Wettbewerbs eines Spiels
        return value;
// defValue: Default-Wert
    }
// return OS2-ID fuer den Spieltyp (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function getGameTypeID(gameType, defValue = __GAMETYPENRN.unbekannt) {
     return getValue(__GAMETYPENRN[gameType], defValue);
}
}


// Liefert einen rechtsbuendigen Text zurueck, der links aufgefuellt wird
// Gibt den Namen eines Wettbewerbs zurueck
// value: Ein uebergebener Wert
// id: OS2-ID des Wettbewerbs eines Spiels (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
// size: Zielbreite (clipping fuer < 0: Abschneiden, falls zu lang)
// defValue: Default-Wert
// char: Zeichen zum Auffuellen
// return Spieltyp fuer die uebergebene OS2-ID
// return Ein String, der mindestens |size| lang ist (oder genau, falls size < 0, also clipping)
function getGameType(id, defValue) {
function padLeft(value, size = 4, char = ' ') {
     return getValue(__GAMETYPES[id], defValue);
     const __SIZE = Math.abs(size);
}
    const __CLIP = (size < 0);
    const __VALUE = (value ? value.toString() : "");
    let i = __VALUE.length;
    let str = "";


    while (i < __SIZE) {
// Gibt den alternativen (Kurznamen) fuer den Namen eines Wettbewerbs zurueck
        str += char;
// gameType: Name des Wettbewerbs eines Spiels
        i += char.length;
// return Normalerweise den uebergebenen Parameter, in Einzelfaellen eine Kurzversion
    }
function getGameTypeAlias(gameType) {
    str = ((i > __SIZE) ? str.slice(0, __SIZE - __VALUE.length - 1) : str) + __VALUE;
     return getValue(__GAMETYPEALIASES[gameType], getValue(gameType, __GAMETYPEALIASES.unbekannt));
 
     return (__CLIP ? str.slice(size) : str);
}
}


// Liefert eine rechtsbuendigen Zahl zurueck, der links (mit Nullen) aufgefuellt wird
// Gibt den Namen des Landes mit dem uebergebenen Kuerzel (TLA) zurueck.
// value: Eine uebergebene Zahl
// tla: Kuerzel (TLA) des Landes
// size: Zielbreite (Default: 2)
// defValue: Default-Wert
// char: Zeichen zum Auffuellen (Default: '0')
// return Name des Landes, 'unbekannt' fuer undefined
// forceClip: Abschneiden erzwingen, falls zu lang?
function getLandName(tla, defValue = __TLALAND[undefined]) {
// return Eine Zahl als String, der mindestens 'size' lang ist (oder genau, falls size < 0, also clipping)
     return getValue(__TLALAND[tla], defValue);
function padNumber(value, size = 2, char = '0') {
     if ((value === 0) || (value && isFinite(value))) {
        return padLeft(value, size, char);
    } else {
        return value;
    }
}
}


// Hilfsfunktionen **********************************************************************
// Gibt die ID des Landes mit dem uebergebenen Namen zurueck.
// land: Name des Landes
// defValue: Default-Wert
// return OS2-ID des Landes, 0 fuer ungueltig
function getLandNr(land, defValue = __LANDNRN.unbekannt) {
    return getValue(__LANDNRN[land], defValue);
}


// Sortiert das Positionsfeld per BubbleSort
// Gibt die ID der Liga mit dem uebergebenen Namen zurueck.
function sortPositionArray(array) {
// land: Name der Liga
     const __TEMP = [];
// defValue: Default-Wert
    let transposed = true;
// return OS2-ID der Liga, 0 fuer ungueltig
    // TOR soll immer die letzte Position im Feld sein, deshalb - 1
function getLigaNr(liga, defValue = __LIGANRN.unbekannt) {
    let length = array.length - 1;
     return getValue(__LIGANRN[liga], defValue);
}


    while (transposed && (length > 1)) {
// Kehrt das Mapping eines Objekts um und liefert ein neues Objekt zurueck.
        transposed = false;
// obj: Objekt mit key => value
        for (let i = 0; i < length - 1; i++) {
// convFun: Konvertierfunktion fuer die Werte
            // Vergleich Opti-Werte:
// return Neues Objekt mit value => key (doppelte value-Werte fallen heraus!)
            if (array[i][1] < array[i + 1][1]) {
function reverseMapping(obj, convFun) {
                // vertauschen
    if (! obj) {
                __TEMP[0] = array[i][0];
         return obj;
                __TEMP[1] = array[i][1];
                array[i][0] = array[i + 1][0];
                array[i][1] = array[i + 1][1];
                array[i + 1][0] = __TEMP[0];
                array[i + 1][1] = __TEMP[1];
                transposed = true;
            }
         }
        length--;
     }
     }
}


// Schaut nach, ob der uebergebene Index zu einem trainierbaren Skill gehoert
     const __RET = { };
// Die Indizes gehen von 0 (SCH) bis 16 (EIN)
 
function isTrainableSkill(idx) {
     for (let key in obj) {
     const __TRAINABLESKILLS = getIdxTrainableSkills();
        const __VALUE = obj[key];
     const __IDX = parseInt(idx, 10);
    let result = false;


    for (let idxTrainable of __TRAINABLESKILLS) {
        __RET[__VALUE] = (convFun ? convFun(key) : key);
        if (__IDX === idxTrainable) {
            result = true;
            break;
        }
     }
     }


     return result;
     return __RET;
}
}


// Gibt alle Skill-Namen zurueck
// ==================== Abschnitt fuer sonstige Parameter ====================
function getAllSkillNames(isGoalie = false) {
    if (isGoalie) {
        return [ 'ABS', 'STS', 'FAN', 'STB', 'SPL', 'REF', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
    } else {
        return [ 'SCH', 'BAK', 'KOB', 'ZWK', 'DEC', 'GES', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
    }
}


// Gibt den Skill-Namen zu einem Index zurueck
// Formatiert eine Zelle um (mit einfachen Parametern)
function getSkillName(idx, isGoalie = false) {
// cell: Zu formatierende Zelle
     const __ALLNAMES = getAllSkillNames(isGoalie);
// bold: Inhalt fett darstellen (true = ja, false = nein)
 
// color: Falls angegeben, die Schriftfarbe
    return __ALLNAMES[idx];
// bgColor: Falls angegeben, die Hintergrundfarbe
}
// opacity: Falls angegeben, die Opazitaet
// return Die formatierte Zelle
function formatCell(cell, bold = true, color = undefined, bgColor = undefined, opacity = undefined) {
     if (cell) {
        if (bold) {
            cell.style.fontWeight = 'bold';
        }
        if (color) {
            cell.style.color = color;
        }
        if (bgColor) {
            cell.style.backgroundColor = bgColor;
        }
        if (opacity) {
        cell.style.opacity = opacity;
        }
    }


// Gibt den Skill-Namen zu einem Index-Array zurueck
     return cell;
function getSkillNameArray(idxArr, isGoalie = false) {
     return (idxArr ? idxArr.map(function(item) {
                                    return getSkillName(item, isGoalie);
                                }) : idxArr);
}
}


// Gibt die Indizes aller Skills zurueck
// Ermittelt die auszugewaehlenden Werte eines Selects (Combo-Box) als Array zurueck
function getIdxAllSkills() {
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
    return [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
}
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
// defValue: Default-Wert, falls nichts selektiert ist
// return Array mit den Options-Werten
function getSelectionArray(element, valType = 'String', valFun = getSelectedValue, defValue = undefined) {
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);


// Gibt die Indizes der trainierbaren Skills zurueck
    return (__SELECT ? [].map.call(__SELECT.options, function(option) {
function getIdxTrainableSkills() {
                                                        return this[valType](getValue(valFun(option), defValue));
    return [ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 15 ];
                                                    }) : undefined);
}
}


// Gibt die Indizes der Fixskills zurueck
// Ermittelt den ausgewaehlten Wert eines Selects (Combo-Box) und gibt diesen zurueck
function getIdxFixSkills() {
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
     return [ 6, 7, 12, 13, 14, 16 ];
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
// defValue: Default-Wert, falls nichts selektiert ist
// return Ausgewaehlter Wert
function getSelection(element, valType = 'String', valFun = getSelectedOptionText, defValue = undefined) {
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);
 
     return this[valType](getValue(valFun(__SELECT), defValue));
}
}


// Gibt die Indizes der Primaerskills zurueck
// Ermittelt den ausgewaehlten Wert einer Combo-Box und gibt diesen zurueck
function getIdxPriSkills(pos) {
// comboBox: Alle 'option'-Eintraege der Combo-Box
    switch (pos) {
// defValue: Default-Wert, falls nichts selektiert ist
        case 'TOR' : return [ 2, 3, 4, 5 ];
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
        case 'ABW' : return [ 2, 3, 4, 15 ];
// return Ausgewaehlter Wert
        case 'DMI' : return [ 1, 4, 9, 11 ];
function getSelectionFromComboBox(comboBox, defValue = undefined, valType = 'String') {
        case 'MIT' : return [ 1, 3, 9, 11 ];
    let selection;
         case 'OMI' : return [ 1, 5, 9, 11 ];
 
         case 'STU' : return [ 0, 2, 3, 5 ];
    for (let i = 0; i < comboBox.length; i++) {
         default :    return [];
         const __ENTRY = comboBox[i];
 
         if (__ENTRY.outerHTML.match(/selected/)) {
            selection = __ENTRY.textContent;
         }
     }
     }
}


// Gibt die Indizes der (trainierbaren) Sekundaerskills zurueck
     return this[valType](getValue(selection, defValue));
function getIdxSecSkills(pos) {
     switch (pos) {
        case 'TOR' : return [ 0, 1, 8, 9, 10, 11, 15 ];
        case 'ABW' : return [ 0, 1, 5, 8, 9, 10, 11 ];
        case 'DMI' : return [ 0, 2, 3, 5, 8, 10, 15 ];
        case 'MIT' : return [ 0, 2, 4, 5, 8, 10, 15 ];
        case 'OMI' : return [ 0, 2, 3, 4, 8, 10, 15 ];
        case 'STU' : return [ 1, 4, 8, 9, 10, 11, 15 ];
        default :    return [];
    }
}
}


// Gibt die zur Position gehoerige Farbe zurueck
// Liefert den Text (textContent) einer selektierten Option
function getColor(pos) {
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
     switch (pos) {
// return Wert der Selektion (textContent)
        case 'TOR' : return "#FFFF00";
function getSelectedOptionText(element) {
        case 'ABW' : return "#00FF00";
     const __SELECTEDOPTIONS = getValue(element, { }).selectedOptions;
        case 'DMI' : return "#3366FF";
    const __OPTION = getValue(__SELECTEDOPTIONS, { })[0];
        case 'MIT' : return "#66FFFF";
 
        case 'OMI' : return "#FF66FF";
    return (__OPTION ? __OPTION.textContent : undefined);
        case 'STU' : return "#FF0000";
}
        case 'LEI' : return "#FFFFFF";
 
        case "" :    return "#111166";  // osBlau
// Liefert den 'value' einer selektierten Option
        default :    return "";
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
     }
// return Wert der Selektion ('value')
function getSelectedValue(element) {
     return getValue(element, { }).value;
}
}


// ==================== Ende Abschnitt genereller Code zur Anzeige der Jugend ====================
// ==================== Ende Abschnitt fuer sonstige Parameter ====================


// ==================== Abschnitt fuer interne IDs auf den Seiten ====================
// ==================== Abschnitt fuer sonstige Parameter des Spielplans ====================


const __GAMETYPENRN = {   // "Blind FSS gesucht!"
const __TEAMSEARCHHAUPT = { // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
         'unbekannt'  : -1,
         'Zeile'  : 0,
        'reserviert' :  0,
         'Spalte' : 1,
        'Frei'      :  0,
         'start'  : " von ",
        'spielfrei'  : 0,
         'middle' : "</b><br>",
         'Friendly'   : 1,
         'liga'   : ". Liga",
         'Liga'       : 2,
         'land'   : ' ',
        'LP'        : 3,
         'end'   : "<a href="
         'OSEQ'       : 4,
         'OSE'       : 5,
         'OSCQ'       : 6,
        'OSC'       :  7,
         'Supercup'   : 10
     };
     };


const __GAMETYPEALIASES = {
const __TEAMSEARCHTEAM = {  // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
        'unbekannt'  : "unbekannt",
         'Zeile' : 0,
         'reserviert' : undefined,
         'Spalte' : 0,
         'Frei'       : undefined,
         'start'  : "<b>",
         'spielfrei'  : "",
         'middle' : " - ",
         'Friendly'   : "FSS",
         'liga'   : ". Liga",
         'Liga'       : undefined,
         'land'   : 'target="_blank">',
        'LP'        :  "Pokal",
         'end'   : "</a></b>"
         'OSEQ'       : undefined,
        'OSE'       :  undefined,
         'OSCQ'       :  undefined,
        'OSC'        :  undefined,
        'Supercup'  : "Super"
     };
     };
const __GAMETYPES = reverseMapping(__GAMETYPENRN);


const __LIGANRN = {
// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
        'unbekannt' : 0,
// cell: Tabellenzelle mit den Parametern zum Team "startTEAMmiddleLIGA...landLANDend", LIGA = "#liga[ (A|B|C|D)]"
        '1. Liga'   : 1,
// teamSeach: Muster fuer die Suche, die Eintraege fuer 'start', 'middle', 'liga', 'land' und 'end' enthaelt
        '2. Liga A' : 2,
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
        '2. Liga B' : 3,
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'LdNr' : 20, 'LgNr' : 1 }
        '3. Liga A' : 4,
function getTeamParamsFromTable(table, teamSearch = undefined) {
        '3. Liga B' : 5,
    const __TEAMSEARCH  = getValue(teamSearch, __TEAMSEARCHHAUPT);
        '3. Liga C' 6,
    const __TEAMCELLROW = getValue(__TEAMSEARCH.Zeile, 0);
        '3. Liga D' 7
    const __TEAMCELLCOL  = getValue(__TEAMSEARCH.Spalte, 0);
     };
    const __TEAMCELLSTR = (table === undefined) ? "" : table.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
const __LIGATYPES = reverseMapping(__LIGANRN);
    const __SEARCHSTART = __TEAMSEARCH.start;
    const __SEARCHMIDDLE = __TEAMSEARCH.middle;
    const __SEARCHLIGA  = __TEAMSEARCH.liga;
    const __SEARCHLAND  = __TEAMSEARCH.land;
     const __SEARCHEND    = __TEAMSEARCH.end;
    const __INDEXSTART  = __TEAMCELLSTR.indexOf(__SEARCHSTART);
    const __INDEXEND    = __TEAMCELLSTR.indexOf(__SEARCHEND);


const __LANDNRN = {
    let teamParams = __TEAMCELLSTR.substring(__INDEXSTART + __SEARCHSTART.length, __INDEXEND);
        'unbekannt'              :  0,
    const __INDEXLIGA = teamParams.indexOf(__SEARCHLIGA);
        'Albanien'              :  45,
    const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);
        'Andorra'                :  95,
 
        'Armenien'              :  83,
    let land = ((~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined);
        'Aserbaidschan'          : 104,
    const __TEAMNAME = ((~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined);
        'Belgien'                :  12,
    let liga = (((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined);
        'Bosnien-Herzegowina'    : 66,
 
        'Bulgarien'              : 42,
    if (land !== undefined) {
        'D\xE4nemark'            :  8,
         if (land.charAt(2) === ' ') {    // Land z.B. hinter "2. Liga A " statt "1. Liga "
        'Deutschland'            :  6,
            land = land.substr(2);
         'England'               :  1,
         }
        'Estland'                :  57,
         if (liga !== undefined) {
         'Far\xF6er'              :  68,
             liga = liga.substring(0, liga.length - land.length);
         'Finnland'              :  40,
         }
        'Frankreich'             :  32,
         const __INDEXLAND = land.indexOf(__SEARCHLAND);
         'Georgien'              :  49,
         if (~ __INDEXLAND) {
         'Griechenland'          :  30,
             land = land.substr(__INDEXLAND + __SEARCHLAND.length);
         'Irland'                :  5,
         }
        'Island'                :  29,
    }
        'Israel'                :  23,
 
        'Italien'                :  10,
    const __TEAM = new Team(__TEAMNAME, land, liga);
        'Kasachstan'             : 105,
 
         'Kroatien'              :  24,
    return __TEAM;
        'Lettland'              :  97,
}
        'Liechtenstein'          :  92,
 
        'Litauen'                :  72,
// Verarbeitet die URL der Seite und ermittelt die Nummer der gewuenschten Unterseite
        'Luxemburg'              :  93,
// url: Adresse der Seite
        'Malta'                  :  69,
// leafs: Liste von Filenamen mit der Default-Seitennummer (falls Query-Parameter nicht gefunden)
        'Mazedonien'            :  86,
// item: Query-Parameter, der die Nummer der Unterseite angibt
        'Moldawien'              :  87,
// return Parameter aus der URL der Seite als Nummer
        'Niederlande'            :  11,
function getPageIdFromURL(url, leafs, item = 'page') {
        'Nordirland'            :  4,
    const __URI = new URI(url);
        'Norwegen'              :   9,
    const __LEAF = __URI.getLeaf();
        '\xD6sterreich'          : 14,
 
        'Polen'                  : 25,
    for (let leaf in leafs) {
        'Portugal'              :  17,
         if (__LEAF === leaf) {
        'Rum\xE4nien'            :  28,
             const __DEFAULT = leafs[leaf];
        'Russland'              :  19,
        'San Marino'             :  98,
        'Schottland'            :  2,
        'Schweden'              :  27,
        'Schweiz'                :  37,
        'Serbien und Montenegro' :  41,
         'Slowakei'              :  70,
        'Slowenien'              :  21,
        'Spanien'                :  13,
        'Tschechien'             :  18,
        'T\xFCrkei'              :  39,
        'Ukraine'                :  20,
        'Ungarn'                :  26,
        'Wales'                  :  3,
        'Weissrussland'          :  71,
        'Zypern'                :  38
    };
const __LAENDER = reverseMapping(__LANDNRN);


const __TLALAND = {
            return getValue(__URI.getQueryPar(item), __DEFAULT);
        undefined : 'unbekannt',
         }
         'ALB'    : 'Albanien',
     }
        'AND'     : 'Andorra',
 
        'ARM'    : 'Armenien',
     return -1;
        'AZE'    : 'Aserbaidschan',
}
        'BEL'    : 'Belgien',
 
        'BIH'     : 'Bosnien-Herzegowina',
// Gibt die laufende Nummer des ZATs im Text einer Zelle zurueck
        'BUL'    : 'Bulgarien',
// cell: Tabellenzelle mit der ZAT-Nummer im Text
        'DEN'    : 'D\xE4nemark',
// return ZAT-Nummer im Text
        'GER'    : 'Deutschland',
function getZATNrFromCell(cell) {
        'ENG'    : 'England',
     const __TEXT = ((cell === undefined) ? [] : cell.textContent.split(' '));
        'EST'    : 'Estland',
     let ZATNr = 0;
        'FRO'    : 'Far\xF6er',
 
        'FIN'     : 'Finnland',
     for (let i = 1; (ZATNr === 0) && (i < __TEXT.length); i++) {
        'FRA'     : 'Frankreich',
         if (__TEXT[i - 1] === "ZAT") {
        'GEO'    : 'Georgien',
            if (__TEXT[i] !== "ist") {
        'GRE'     : 'Griechenland',
                ZATNr = parseInt(__TEXT[i], 10);
         'IRL'    : 'Irland',
            }
        'ISL'    : 'Island',
         }
        'ISR'    : 'Israel',
     }
        'ITA'    : 'Italien',
 
         'KAZ'    : 'Kasachstan',
     return ZATNr;
        'CRO'     : 'Kroatien',
}
        'LVA'    : 'Lettland',
 
        'LIE'     : 'Liechtenstein',
// ==================== Ende Abschnitt fuer sonstige Parameter des Spielplans ====================
        'LTU'    : 'Litauen',
        'LUX'    : 'Luxemburg',
        'MLT'    : 'Malta',
        'MKD'    : 'Mazedonien',
        'MDA'    : 'Moldawien',
        'NED'    : 'Niederlande',
        'NIR'    : 'Nordirland',
        'NOR'    : 'Norwegen',
        'AUT'    : '\xD6sterreich',
        'POL'    : 'Polen',
        'POR'    : 'Portugal',
        'ROM'    : 'Rum\xE4nien',
        'RUS'    : 'Russland',
        'SMR'    : 'San Marino',
        'SCO'    : 'Schottland',
        'SWE'    : 'Schweden',
        'SUI'    : 'Schweiz',
        'SCG'    : 'Serbien und Montenegro',
        'SVK'    : 'Slowakei',
        'SVN'    : 'Slowenien',
        'ESP'    : 'Spanien',
        'CZE'    : 'Tschechien',
        'TUR'    : 'T\xFCrkei',
        'UKR'    : 'Ukraine',
        'HUN'    : 'Ungarn',
        'WAL'    : 'Wales',
        'BLR'    : 'Weissrussland',
        'CYP'    : 'Zypern'
    };
const __LANDTLAS = reverseMapping(__TLALAND);


// ==================== Abschnitt fuer Daten des Spielplans ====================
// ==================== Ende Abschnitt fuer Spielplan und ZATs ====================


// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
// ==================== Hauptprogramm ====================
// gameType: Name des Wettbewerbs eines Spiels
// defValue: Default-Wert
// return OS2-ID fuer den Spieltyp (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function getGameTypeID(gameType, defValue = __GAMETYPENRN.unbekannt) {
    return getValue(__GAMETYPENRN[gameType], defValue);
}


// Gibt den Namen eines Wettbewerbs zurueck
// Verarbeitet Ansicht "Haupt" (Managerbuero) zur Ermittlung des aktuellen ZATs
// id: OS2-ID des Wettbewerbs eines Spiels (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function procHaupt() {
// defValue: Default-Wert
     const __TEAMPARAMS = getTeamParamsFromTable(getTable(1), __TEAMSEARCHHAUPT); // Link mit Team, Liga, Land...
// return Spieltyp fuer die uebergebene OS2-ID
function getGameType(id, defValue) {
     return getValue(__GAMETYPES[id], defValue);
}


// Gibt den alternativen (Kurznamen) fuer den Namen eines Wettbewerbs zurueck
    return buildOptions(__OPTCONFIG, __OPTSET, {
// gameType: Name des Wettbewerbs eines Spiels
                            'teamParams' : __TEAMPARAMS,
// return Normalerweise den uebergebenen Parameter, in Einzelfaellen eine Kurzversion
                            'hideMenu'  : true
function getGameTypeAlias(gameType) {
                        }).then(async optSet => {
    return getValue(__GAMETYPEALIASES[gameType], getValue(gameType, __GAMETYPEALIASES.unbekannt));
            const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
}
            const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
            const __CURRZAT = __NEXTZAT - 1;
            const __DATAZAT = getOptValue(__OPTSET.datenZat);


// Gibt den Namen des Landes mit dem uebergebenen Kuerzel (TLA) zurueck.
            // Stand der alten Daten merken...
// tla: Kuerzel (TLA) des Landes
            setOpt(__OPTSET.oldDatenZat, __DATAZAT, false);
// defValue: Default-Wert
// return Name des Landes, 'unbekannt' fuer undefined
function getLandName(tla, defValue = __TLALAND[undefined]) {
    return getValue(__TLALAND[tla], defValue);
}


// Gibt die ID des Landes mit dem uebergebenen Namen zurueck.
            if (__CURRZAT >= 0) {
// land: Name des Landes
                __LOG[2]("Aktueller ZAT: " + __CURRZAT);
// defValue: Default-Wert
// return OS2-ID des Landes, 0 fuer ungueltig
function getLandNr(land, defValue = __LANDNRN.unbekannt) {
    return getValue(__LANDNRN[land], defValue);
}


// Gibt die ID der Liga mit dem uebergebenen Namen zurueck.
                // Neuen aktuellen ZAT speichern...
// land: Name der Liga
                setOpt(__OPTSET.aktuellerZat, __CURRZAT, false);
// defValue: Default-Wert
// return OS2-ID der Liga, 0 fuer ungueltig
function getLigaNr(liga, defValue = __LIGANRN.unbekannt) {
    return getValue(__LIGANRN[liga], defValue);
}


// Kehrt das Mapping eines Objekts um und liefert ein neues Objekt zurueck.
                if (__CURRZAT !== __DATAZAT) {
// obj: Objekt mit key => value
                    __LOG[2](__LOG.changed(__DATAZAT, __CURRZAT));
// convFun: Konvertierfunktion fuer die Werte
// return Neues Objekt mit value => key (doppelte value-Werte fallen heraus!)
function reverseMapping(obj, convFun) {
    if (! obj) {
        return obj;
    }


    const __RET = { };
                    // ... und ZAT-bezogene Daten als veraltet markieren (ausser 'skills' und 'positions')
                    await __TEAMCLASS.deleteOptions({
                                                    'skills'      : true,
                                                    'positions'  : true,
                                                    'datenZat'    : true,
                                                    'oldDatenZat' : true
                                                }).catch(defaultCatch);


    for (let key in obj) {
                    // Neuen Daten-ZAT speichern...
         const __VALUE = obj[key];
                    setOpt(__OPTSET.datenZat, __CURRZAT, false);
                }
            }
         });
}


        __RET[__VALUE] = (convFun ? convFun(key) : key);
// Verarbeitet Ansicht "Optionen" zur Ermittlung der Jugendfoerderung
    }
function procOptionen() {
 
    return buildOptions(__OPTCONFIG, __OPTSET, {
    return __RET;
                            'menuAnchor'  : getTable(0, 'div'),
                            'hideMenu'    : true,
                            'getDonation' : true,
                            'showForm'    : {
                                                'foerderung'    : true,
                                                'showForm'      : true
                                            }
        });
}
}


// ==================== Abschnitt fuer sonstige Parameter ====================
// Verarbeitet Ansicht "Teamuebersicht"
function procTeamuebersicht() {
    const __ROWOFFSETUPPER = 1;    // Header-Zeile
    const __ROWOFFSETLOWER = 1;    // Ziehen-Button


// Formatiert eine Zelle um (mit einfachen Parametern)
    const __COLUMNINDEX = {
// cell: Zu formatierende Zelle
            'Age'  : 0,
// bold: Inhalt fett darstellen (true = ja, false = nein)
            'Geb'  : 1,
// color: Falls angegeben, die Schriftfarbe
            'Flg'  : 2,
// bgColor: Falls angegeben, die Hintergrundfarbe
            'Land'  : 3,
// opacity: Falls angegeben, die Opazitaet
            'U'    : 4,
// return Die formatierte Zelle
            'Skill' : 5,
function formatCell(cell, bold = true, color = undefined, bgColor = undefined, opacity = undefined) {
            'Tal'  : 6,
    if (cell) {
             'Akt'   : 7,
        if (bold) {
             'Auf'  : 8,
             cell.style.fontWeight = 'bold';
             'Zus'  : 9
        }
         };
        if (color) {
             cell.style.color = color;
        }
        if (bgColor) {
             cell.style.backgroundColor = bgColor;
         }
        if (opacity) {
        cell.style.opacity = opacity;
        }
    }


     return cell;
     if (getElement('transfer') !== undefined) {
}
        __LOG[2]("Ziehen-Seite");
    } else if (getRows(1) === undefined) {
        __LOG[2]("Diese Seite ist ohne Team nicht verf\xFCgbar!");
    } else {
        return buildOptions(__OPTCONFIG, __OPTSET, {
                                'menuAnchor' : getTable(0, 'div'),
                                'showForm'  : {
                                                  'kennzeichenEnde'    : true,
                                                  'shortAufw'          : true,
                                                  'sepStyle'          : true,
                                                  'sepColor'          : true,
                                                  'sepWidth'          : true,
                                                  'saison'            : true,
                                                  'aktuellerZat'      : true,
                                                  'foerderung'        : true,
                                                  'team'              : true,
                                                  'zeigeBalken'        : true,
                                                  'absBalken'          : true,
                                                  'zeigeId'            : true,
                                                  'ersetzeAlter'      : true,
                                                  'zeigeAlter'        : true,
                                                  'zeigeQuote'        : true,
                                                  'zeigePosition'      : true,
                                                  'zeigeZatDone'      : true,
                                                  'zeigeZatLeft'      : true,
                                                  'zeigeFixSkills'    : true,
                                                  'zeigeTrainiert'    : true,
                                                  'zeigeAnteilPri'    : true,
                                                  'zeigeAnteilSec'    : true,
                                                  'zeigePrios'        : true,
                                                  'zeigeSkill'        : true,
                                                  'anzahlOpti'        : true,
                                                  'anzahlMW'          : true,
                                                  'zeigeTrainiertEnde' : true,
                                                  'zeigeAnteilPriEnde' : true,
                                                  'zeigeAnteilSecEnde' : true,
                                                  'zeigePriosEnde'    : true,
                                                  'zeigeSkillEnde'    : true,
                                                  'anzahlOptiEnde'    : true,
                                                  'anzahlMWEnde'      : true,
                                                  'zatAges'            : true,
                                                  'trainiert'          : true,
                                                  'positions'          : true,
                                                  'skills'            : true,
                                                  'reset'              : true,
                                                  'showForm'          : true
                                              },
                                'formWidth'  : 1
                            }).then(optSet => {
                const __ROWS = getRows(1);
                const __HEADERS = __ROWS[0];
                const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"


// Ermittelt die auszugewaehlenden Werte eines Selects (Combo-Box) als Array zurueck
                const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, true);
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
                const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, {
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
                                                    'Default'           : true,
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
                                                    'ersetzeSkills'     : false,
// defValue: Default-Wert, falls nichts selektiert ist
                                                    'zeigeGeb'           : false,
// return Array mit den Options-Werten
                                                    'zeigeSkill'         : false,
function getSelectionArray(element, valType = 'String', valFun = getSelectedValue, defValue = undefined) {
                                                    'zeigeTal'           : false,
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);
                                                    'zeigeAufw'         : false
                                                });


    return (__SELECT ? [].map.call(__SELECT.options, function(option) {
                __COLMAN.addTitles(__HEADERS, __TITLECOLOR);
                                                        return this[valType](getValue(valFun(option), defValue));
                                                    }) : undefined);
}


// Ermittelt den ausgewaehlten Wert eines Selects (Combo-Box) und gibt diesen zurueck
                for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
                    if (__ROWS[i].cells.length > 1) {
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
                        __COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
                    }
// defValue: Default-Wert, falls nichts selektiert ist
                }
// return Ausgewaehlter Wert
function getSelection(element, valType = 'String', valFun = getSelectedOptionText, defValue = undefined) {
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);


    return this[valType](getValue(valFun(__SELECT), defValue));
                // Format der Trennlinie zwischen den Jahrgaengen...
}
                //const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);


// Ermittelt den ausgewaehlten Wert einer Combo-Box und gibt diesen zurueck
                //separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Age, __ROWOFFSETUPPER, __ROWOFFSETLOWER, -1, 0, floorValue);
// comboBox: Alle 'option'-Eintraege der Combo-Box
            });
// defValue: Default-Wert, falls nichts selektiert ist
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
// return Ausgewaehlter Wert
function getSelectionFromComboBox(comboBox, defValue = undefined, valType = 'String') {
    let selection;
 
    for (let i = 0; i < comboBox.length; i++) {
        const __ENTRY = comboBox[i];
 
        if (__ENTRY.outerHTML.match(/selected/)) {
            selection = __ENTRY.textContent;
        }
     }
     }


     return this[valType](getValue(selection, defValue));
    // Promise fuer alle Faelle ohne Rueckgabewert...
     return Promise.resolve();
}
}


// Liefert den Text (textContent) einer selektierten Option
// Verarbeitet Ansicht "Spielereinzelwerte"
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
function procSpielereinzelwerte() {
// return Wert der Selektion (textContent)
     const __ROWOFFSETUPPER = 1;     // Header-Zeile
function getSelectedOptionText(element) {
     const __ROWOFFSETLOWER = 0;
     const __SELECTEDOPTIONS = getValue(element, { }).selectedOptions;
     const __OPTION = getValue(__SELECTEDOPTIONS, { })[0];


     return (__OPTION ? __OPTION.textContent : undefined);
     const __COLUMNINDEX = {
}
            'Flg'  : 0,
            'Land'  : 1,
            'U'    : 2,
            'X'    : 3,
            'Age'  : 4,
            'Einz'  : 5,    // ab hier die Einzelskills
            'SCH'  : 5,
            'ABS'  : 5,    // TOR
            'BAK'  : 6,
            'STS'  : 6,    // TOR
            'KOB'  : 7,
            'FAN'  : 7,    // TOR
            'ZWK'  : 8,
            'STB'  : 8,    // TOR
            'DEC'  : 9,
            'SPL'  : 9,    // TOR
            'GES'  : 10,
            'REF'  : 10,  // TOR
            'FUQ'  : 11,
            'ERF'  : 12,
            'AGG'  : 13,
            'PAS'  : 14,
            'AUS'  : 15,
            'UEB'  : 16,
            'WID'  : 17,
            'SEL'  : 18,
            'DIS'  : 19,
            'ZUV'  : 20,
            'EIN'  : 21,
            'Zus'  : 22    // Zusaetze hinter den Einzelskills
        };


// Liefert den 'value' einer selektierten Option
    if (getRows(1) === undefined) {
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
        __LOG[2]("Diese Seite ist ohne Team nicht verf\xFCgbar!");
// return Wert der Selektion ('value')
    } else {
function getSelectedValue(element) {
        return buildOptions(__OPTCONFIG, __OPTSET, {
     return getValue(element, { }).value;
                                'menuAnchor' : getTable(0, 'div'),
}
                                'hideForm'  : {
 
                                                  'zatAges'       : true,
// ==================== Ende Abschnitt fuer sonstige Parameter ====================
                                                  'trainiert'     : true,
                                                  'positions'     : true,
                                                  'skills'        : true,
                                                  'shortAufw'     : true
                                              },
                                'formWidth'  : 1
                            }).then(optSet => {
                const __ROWS = getRows(1);
                const __HEADERS = __ROWS[0];
                const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"


// ==================== Abschnitt fuer sonstige Parameter des Spielplans ====================
                const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, false);
                const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, true);


const __TEAMSEARCHHAUPT = {  // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
                __COLMAN.addTitles(__HEADERS, __TITLECOLOR);
        'Zeile'  : 0,
        'Spalte' : 1,
        'start'  : " von ",
        'middle' : "</b><br>",
        'liga'  : ". Liga",
        'land'  : ' ',
        'end'    : "<a href="
    };


const __TEAMSEARCHTEAM = {  // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
                for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
        'Zeile'  : 0,
                    if (__ROWS[i].cells.length > 1) {
        'Spalte' : 0,
                        __COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
        'start'  : "<b>",
                    }
        'middle' : " - ",
                }
        'liga'  : ". Liga",
        'land'  : 'target="_blank">',
        'end'    : "</a></b>"
    };


// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
                // Format der Trennlinie zwischen den Jahrgaengen...
// cell: Tabellenzelle mit den Parametern zum Team "startTEAMmiddleLIGA...landLANDend", LIGA = "#liga[ (A|B|C|D)]"
                //const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);
// teamSeach: Muster fuer die Suche, die Eintraege fuer 'start', 'middle', 'liga', 'land' und 'end' enthaelt
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'LdNr' : 20, 'LgNr' : 1 }
function getTeamParamsFromTable(table, teamSearch = undefined) {
    const __TEAMSEARCH  = getValue(teamSearch, __TEAMSEARCHHAUPT);
    const __TEAMCELLROW  = getValue(__TEAMSEARCH.Zeile, 0);
    const __TEAMCELLCOL  = getValue(__TEAMSEARCH.Spalte, 0);
    const __TEAMCELLSTR  = (table === undefined) ? "" : table.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
    const __SEARCHSTART  = __TEAMSEARCH.start;
    const __SEARCHMIDDLE = __TEAMSEARCH.middle;
    const __SEARCHLIGA  = __TEAMSEARCH.liga;
    const __SEARCHLAND  = __TEAMSEARCH.land;
    const __SEARCHEND    = __TEAMSEARCH.end;
    const __INDEXSTART  = __TEAMCELLSTR.indexOf(__SEARCHSTART);
    const __INDEXEND    = __TEAMCELLSTR.indexOf(__SEARCHEND);


    let teamParams = __TEAMCELLSTR.substring(__INDEXSTART + __SEARCHSTART.length, __INDEXEND);
                //separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Age, __ROWOFFSETUPPER, __ROWOFFSETLOWER, -1, 0, floorValue);
    const __INDEXLIGA = teamParams.indexOf(__SEARCHLIGA);
            });
    const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);
 
    let land = ((~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined);
    const __TEAMNAME = ((~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined);
    let liga = (((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined);
 
    if (land !== undefined) {
        if (land.charAt(2) === ' ') {    // Land z.B. hinter "2. Liga A " statt "1. Liga "
            land = land.substr(2);
        }
        if (liga !== undefined) {
            liga = liga.substring(0, liga.length - land.length);
        }
        const __INDEXLAND = land.indexOf(__SEARCHLAND);
        if (~ __INDEXLAND) {
            land = land.substr(__INDEXLAND + __SEARCHLAND.length);
        }
     }
     }


     const __TEAM = new Team(__TEAMNAME, land, liga);
     // Promise fuer alle Faelle ohne Rueckgabewert...
 
     return Promise.resolve();
     return __TEAM;
}
}


// Verarbeitet die URL der Seite und ermittelt die Nummer der gewuenschten Unterseite
// Verarbeitet Ansicht "Opt. Skill"
// url: Adresse der Seite
function procOptSkill() {
// leafs: Liste von Filenamen mit der Default-Seitennummer (falls Query-Parameter nicht gefunden)
     const __ROWOFFSETUPPER = 1;     // Header-Zeile
// item: Query-Parameter, der die Nummer der Unterseite angibt
     const __ROWOFFSETLOWER = 0;
// return Parameter aus der URL der Seite als Nummer
function getPageIdFromURL(url, leafs, item = 'page') {
     const __URI = new URI(url);
     const __LEAF = __URI.getLeaf();


    for (let leaf in leafs) {
     const __COLUMNINDEX = {
        if (__LEAF === leaf) {
             'Flg'  : 0,
            const __DEFAULT = leafs[leaf];
             'Land'  : 1,
 
             'U'    : 2,
            return getValue(__URI.getQueryPar(item), __DEFAULT);
             'Age'   : 3,
        }
             'Skill' : 4,
    }
             'TOR'  : 5,
 
             'ABW'  : 6,
    return -1;
             'DMI'  : 7,
}
             'MIT'  : 8,
 
             'OMI'  : 9,
// Gibt die laufende Nummer des ZATs im Text einer Zelle zurueck
             'STU'  : 10,
// cell: Tabellenzelle mit der ZAT-Nummer im Text
             'Zus'  : 11    // Zusaetze hinter den OptSkills
// return ZAT-Nummer im Text
function getZATNrFromCell(cell) {
    const __TEXT = ((cell === undefined) ? [] : cell.textContent.split(' '));
    let ZATNr = 0;
 
    for (let i = 1; (ZATNr === 0) && (i < __TEXT.length); i++) {
        if (__TEXT[i - 1] === "ZAT") {
            if (__TEXT[i] !== "ist") {
                ZATNr = parseInt(__TEXT[i], 10);
            }
        }
    }
 
    return ZATNr;
}
 
// ==================== Ende Abschnitt fuer sonstige Parameter des Spielplans ====================
 
// ==================== Ende Abschnitt fuer Spielplan und ZATs ====================
 
// ==================== Hauptprogramm ====================
 
// Verarbeitet Ansicht "Haupt" (Managerbuero) zur Ermittlung des aktuellen ZATs
function procHaupt() {
    const __TEAMPARAMS = getTeamParamsFromTable(getTable(1), __TEAMSEARCHHAUPT);  // Link mit Team, Liga, Land...
 
    return buildOptions(__OPTCONFIG, __OPTSET, {
                            'teamParams' : __TEAMPARAMS,
//                            'menuAnchor' : getTable(0, 'div'),
                            'hideMenu'  : true,
                            'showForm'  : {
                                              'zeigeWarnung'        : true,
                                              'zeigeWarnungMonat'    : true,
                                              'zeigeWarnungHome'    : true,
                                              'zeigeWarnungDialog'  : true,
                                              'zeigeWarnungAufstieg' : true,
                                              'zeigeWarnungLegende'  : true,
                                              'ziehAnz'              : true,
                                              'showForm'            : true
                                          }
                        }).then(async optSet => {
            const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
            const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
            const __CURRZAT = __NEXTZAT - 1;
            const __DATAZAT = getOptValue(__OPTSET.datenZat);
 
            // Stand der alten Daten merken...
            setOpt(__OPTSET.oldDatenZat, __DATAZAT, false);
 
            if (__CURRZAT >= 0) {
                __LOG[2]("Aktueller ZAT: " + __CURRZAT);
 
                // Neuen aktuellen ZAT speichern...
                setOpt(__OPTSET.aktuellerZat, __CURRZAT, false);
 
                if (__CURRZAT !== __DATAZAT) {
                    __LOG[2](__LOG.changed(__DATAZAT, __CURRZAT));
 
                    // ... und ZAT-bezogene Daten als veraltet markieren (ausser 'skills', 'positions' und 'ziehAnz')
                    await __TEAMCLASS.deleteOptions({
                                                    'skills'      : true,
                                                    'positions'  : true,
                                                    'datenZat'    : true,
                                                    'oldDatenZat' : true,
                                                    'ziehAnz'    : (__CURRZAT > __DATAZAT)  // nur loeschen, wenn < __DATAZAT
                                                }).catch(defaultCatch);
 
                    // Neuen Daten-ZAT speichern...
                    setOpt(__OPTSET.datenZat, __CURRZAT, false);
                }
            }
 
            const __MSG = new WarnDrawMessage(optSet, __CURRZAT);
            const __MSGAUFSTIEG = new WarnDrawMessageAufstieg(optSet, __CURRZAT);
            const __ANCHOR = getTable(0, 'tbody');
 
            __MSG.showMessage(__ANCHOR, 'tr', true);
            __MSG.showDialog(showAlert);
            __MSGAUFSTIEG.showMessage(__ANCHOR, 'tr', true);
        });
}
 
// Verarbeitet Ansicht "Optionen" zur Ermittlung der Jugendfoerderung
function procOptionen() {
    return buildOptions(__OPTCONFIG, __OPTSET, {
                            'menuAnchor'  : getTable(0, 'div'),
                            'hideMenu'    : true,
                            'getDonation' : true,
                            'showForm'    : {
                                                'foerderung'          : true,
                                                'zeigeWarnung'        : true,
                                                'zeigeWarnungMonat'    : true,
                                                'zeigeWarnungHome'    : true,
                                                'zeigeWarnungDialog'  : true,
                                                'zeigeWarnungAufstieg' : true,
                                                'zeigeWarnungLegende'  : true,
                                                'ziehAnz'              : true,
                                                'showForm'            : true
                                            }
        });
}
 
// Verarbeitet Ansicht "Teamuebersicht"
function procTeamuebersicht() {
    const __ROWOFFSETUPPER = 1;    // Header-Zeile
    const __ROWOFFSETLOWER = 1;    // Ziehen-Button
 
    const __COLUMNINDEX = {
            'Age'  : 0,
            'Geb'  : 1,
            'Flg'  : 2,
            'Land'  : 3,
            'U'    : 4,
            'Skill' : 5,
            'Tal'  : 6,
            'Akt'  : 7,
            'Auf'  : 8,
            'Zus'  : 9
        };
 
    if (getElement('transfer') !== undefined) {
        __LOG[2]("Ziehen-Seite");
    } else if (getRows(1) === undefined) {
        __LOG[2]("Diese Seite ist ohne Team nicht verf\xFCgbar!");
    } else {
        return buildOptions(__OPTCONFIG, __OPTSET, {
                                'menuAnchor' : getTable(0, 'div'),
                                'showForm'  : {
                                                  'kennzeichenEnde'      : true,
                                                  'shortAufw'            : true,
                                                  'sepStyle'            : true,
                                                  'sepColor'            : true,
                                                  'sepWidth'            : true,
                                                  'saison'              : true,
                                                  'aktuellerZat'        : true,
                                                  'foerderung'          : true,
                                                  'team'                : true,
                                                  'zeigeJahrgang'        : true,
                                                  'zeigeUxx'            : true,
                                                  'zeigeWarnung'        : true,
                                                  'zeigeWarnungMonat'    : true,
                                                  'zeigeWarnungHome'    : true,
                                                  'zeigeWarnungDialog'  : true,
                                                  'zeigeWarnungAufstieg' : true,
                                                  'zeigeWarnungLegende'  : true,
                                                  'zeigeBalken'          : true,
                                                  'absBalken'            : true,
                                                  'zeigeId'              : true,
                                                  'ersetzeAlter'        : true,
                                                  'zeigeAlter'          : true,
                                                  'zeigeQuote'          : true,
                                                  'zeigePosition'        : true,
                                                  'zeigeZatDone'        : true,
                                                  'zeigeZatLeft'        : true,
                                                  'zeigeFixSkills'      : true,
                                                  'zeigeTrainiert'      : true,
                                                  'zeigeAnteilPri'      : true,
                                                  'zeigeAnteilSec'      : true,
                                                  'zeigePrios'          : true,
                                                  'anzahlOpti'          : true,
                                                  'anzahlMW'            : true,
                                                  'zeigeTrainiertEnde'  : true,
                                                  'zeigeAnteilPriEnde'  : true,
                                                  'zeigeAnteilSecEnde'  : true,
                                                  'zeigePriosEnde'      : true,
                                                  'zeigeSkillEnde'      : true,
                                                  'anzahlOptiEnde'      : true,
                                                  'anzahlMWEnde'        : true,
                                                  'ziehAnz'              : true,
                                                  'zatAges'              : true,
                                                  'trainiert'            : true,
                                                  'positions'            : true,
                                                  'skills'              : true,
                                                  'reset'                : true,
                                                  'showForm'            : true
                                              },
                                'formWidth'  : 1
                            }).then(optSet => {
                const __ROWS = getRows(1);
                const __HEADERS = __ROWS[0];
                const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"
 
                const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 1);
                const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, {
                                                    'Default'            : true,
                                                    'ersetzeSkills'      : false,
                                                    'zeigeGeb'          : false,
                                                    'zeigeSkill'        : false,
                                                    'zeigeTal'          : false,
                                                    'zeigeAufw'          : false
                                                });
 
                __COLMAN.addTitles(__HEADERS, __TITLECOLOR);
 
                for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
                    if (__ROWS[i].cells.length > 1) {
                        __COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
                    } else {
                        __COLMAN.setGroupTitle(__ROWS[i]);
                    }
                }
 
                // Format der Trennlinie zwischen den Jahrgaengen...
                if (! __COLMAN.gt) {
                    const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);
 
                    separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Land, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 0, 0, existValue);
                }
 
                const __CURRZAT = getOptValue(__OPTSET.datenZat);
                const __MSG = new WarnDrawMessage(__OPTSET, __CURRZAT);
                const __MSGAUFSTIEG = new WarnDrawMessageAufstieg(__OPTSET, __CURRZAT);
                const __ANCHOR = getTable(0, 'div');
                const __SEARCH = '<form method="POST">';
 
                // Kompaktere Darstellung und ohne Links...
                __MSG.out.top = false;
                __MSG.out.label = false;
                __MSG.out.link = false;
                __MSG.out.bottom = false;
                __MSGAUFSTIEG.out.label = false;
                __MSGAUFSTIEG.out.link = false;
                __MSGAUFSTIEG.out.bottom = false;
 
                __MSG.setOptionLegende();
                __MSGAUFSTIEG.setOptionLegende();
 
                __MSG.showMessage(__ANCHOR, 'p', __SEARCH);
                __MSGAUFSTIEG.showMessage(__ANCHOR, 'p', __SEARCH);
            });
    }
 
    // Promise fuer alle Faelle ohne Rueckgabewert...
    return Promise.resolve();
}
 
// Verarbeitet Ansicht "Spielereinzelwerte"
function procSpielereinzelwerte() {
    const __ROWOFFSETUPPER = 1;    // Header-Zeile
    const __ROWOFFSETLOWER = 0;
 
     const __COLUMNINDEX = {
             'Flg'  : 0,
             'Land'  : 1,
             'U'    : 2,
             'X'     : 3,
             'Age'   : 4,
             'Einz'  : 5,    // ab hier die Einzelskills
            'SCH'  : 5,
            'ABS'  : 5,   // TOR
             'BAK'  : 6,
             'STS'  : 6,    // TOR
            'KOB'  : 7,
             'FAN'  : 7,    // TOR
            'ZWK'  : 8,
             'STB'  : 8,    // TOR
            'DEC'  : 9,
            'SPL'  : 9,   // TOR
             'GES'  : 10,
             'REF'  : 10,  // TOR
            'FUQ'  : 11,
            'ERF'  : 12,
            'AGG'  : 13,
            'PAS'  : 14,
            'AUS'  : 15,
            'UEB'  : 16,
            'WID'  : 17,
            'SEL'  : 18,
            'DIS'  : 19,
            'ZUV'  : 20,
            'EIN'  : 21,
            'Zus'  : 22     // Zusaetze hinter den Einzelskills
         };
         };


Zeile 6.489: Zeile 5.983:
                                 'menuAnchor' : getTable(0, 'div'),
                                 'menuAnchor' : getTable(0, 'div'),
                                 'hideForm'  : {
                                 'hideForm'  : {
                                                  'zeigeWarnung'        : false,
                                                   'zatAges'       : true,
                                                  'zeigeWarnungMonat'    : false,
                                                   'trainiert'     : true,
                                                  'zeigeWarnungHome'    : false,
                                                   'positions'     : true,
                                                  'zeigeWarnungDialog'  : false,
                                                   'skills'       : true,
                                                  'zeigeWarnungAufstieg' : false,
                                                   'shortAufw'     : true
                                                  'zeigeWarnungLegende'  : false,
                                                  'ziehAnz'              : true,
                                                   'zatAges'             : true,
                                                   'trainiert'           : true,
                                                   'positions'           : true,
                                                   'skills'               : true,
                                                   'shortAufw'           : true
                                               },
                                               },
                                 'formWidth'  : 1
                                 'formWidth'  : 1
Zeile 6.508: Zeile 5.995:
                 const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"
                 const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"


                 const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 2);
                 const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, false);
                 const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, true);
                 const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, true);


                __COLMAN.addTitles(__HEADERS, __TITLECOLOR);
                 //__COLMAN.addTitles(__HEADERS, __TITLECOLOR);
 
                for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
                    if (__ROWS[i].cells.length > 1) {
                        __COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
                    } else {
                        __COLMAN.setGroupTitle(__ROWS[i]);
                    }
                }
 
                 // Format der Trennlinie zwischen den Jahrgaengen...
                if (! __COLMAN.gt) {
                    const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);
 
                    separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Land, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 0, 0, existValue);
                }
            });
    }
 
    // Promise fuer alle Faelle ohne Rueckgabewert...
    return Promise.resolve();
}
 
// Verarbeitet Ansicht "Opt. Skill"
function procOptSkill() {
    const __ROWOFFSETUPPER = 1;    // Header-Zeile
    const __ROWOFFSETLOWER = 0;
 
    const __COLUMNINDEX = {
            'Flg'  : 0,
            'Land'  : 1,
            'U'    : 2,
            'Age'  : 3,
            'Skill' : 4,
            'TOR'  : 5,
            'ABW'  : 6,
            'DMI'  : 7,
            'MIT'  : 8,
            'OMI'  : 9,
            'STU'  : 10,
            'Zus'  : 11    // Zusaetze hinter den OptSkills
        };
 
    if (getRows(1) === undefined) {
        __LOG[2]("Diese Seite ist ohne Team nicht verf\xFCgbar!");
    } else {
        return buildOptions(__OPTCONFIG, __OPTSET, {
                                'menuAnchor' : getTable(0, 'div'),
                                'showForm'  : {
                                                  'kennzeichenEnde'      : true,
                                                  'sepStyle'            : true,
                                                  'sepColor'            : true,
                                                  'sepWidth'            : true,
                                                  'saison'              : true,
                                                  'aktuellerZat'        : true,
                                                  'foerderung'          : true,
                                                  'team'                : true,
                                                  'zeigeJahrgang'        : true,
                                                  'zeigeUxx'            : true,
                                                  'zeigeWarnung'        : false,
                                                  'zeigeWarnungMonat'    : false,
                                                  'zeigeWarnungHome'    : false,
                                                  'zeigeWarnungDialog'  : false,
                                                  'zeigeWarnungAufstieg' : false,
                                                  'zeigeWarnungLegende'  : false,
                                                  'zeigeBalken'          : true,
                                                  'absBalken'            : true,
                                                  'zeigeId'              : true,
                                                  'ersetzeAlter'        : true,
                                                  'zeigeAlter'          : true,
                                                  'zeigeQuote'          : true,
                                                  'zeigePosition'        : true,
                                                  'zeigeZatDone'        : true,
                                                  'zeigeZatLeft'        : true,
                                                  'zeigeFixSkills'      : true,
                                                  'zeigeTrainiert'      : true,
                                                  'zeigeAnteilPri'      : true,
                                                  'zeigeAnteilSec'      : true,
                                                  'zeigePrios'          : true,
                                                  'zeigeAufw'            : true,
                                                  'zeigeGeb'            : true,
                                                  'zeigeTal'            : true,
                                                  'anzahlOpti'          : true,
                                                  'anzahlMW'            : true,
                                                  'zeigeTrainiertEnde'  : true,
                                                  'zeigeAnteilPriEnde'  : true,
                                                  'zeigeAnteilSecEnde'  : true,
                                                  'zeigePriosEnde'      : true,
                                                  'zeigeSkillEnde'      : true,
                                                  'anzahlOptiEnde'      : true,
                                                  'anzahlMWEnde'        : true,
                                                  'zatAges'              : true,
                                                  'trainiert'            : true,
                                                  'positions'            : true,
                                                  'skills'              : true,
                                                  'reset'                : true,
                                                  'showForm'            : true
                                              },
                                'formWidth'  : 1
                            }).then(optSet => {
                const __ROWS = getRows(1);
                const __HEADERS = __ROWS[0];
                const __TITLECOLOR = getColor('LEI');  // "#FFFFFF"
 
                const __PLAYERS = init(__ROWS, __OPTSET, __COLUMNINDEX, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 3);
                const __COLMAN = new ColumnManager(__OPTSET, __COLUMNINDEX, {
                                                    'Default'            : true,
                                                    'ersetzeSkills'      : false,
                                                    'zeigeSkill'        : false
                                                });
 
                __COLMAN.addTitles(__HEADERS, __TITLECOLOR);


                 for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
                 for (let i = __ROWOFFSETUPPER, j = 0; i < __ROWS.length - __ROWOFFSETLOWER; i++) {
                     if (__ROWS[i].cells.length > 1) {
                     if (__ROWS[i].cells.length > 1) {
                         __COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
                         //__COLMAN.addValues(__PLAYERS[j++], __ROWS[i], __TITLECOLOR);
                    } else {
                        __COLMAN.setGroupTitle(__ROWS[i]);
                     }
                     }
                 }
                 }


                 // Format der Trennlinie zwischen den Jahrgaengen...
                 // Format der Trennlinie zwischen den Jahrgaengen...
                 if (! __COLMAN.gt) {
                 //const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);
                    const __BORDERSTRING = getOptValue(__OPTSET.sepStyle) + ' ' + getOptValue(__OPTSET.sepColor) + ' ' + getOptValue(__OPTSET.sepWidth);


                    separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Land, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 0, 0, existValue);
                //separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Age, __ROWOFFSETUPPER, __ROWOFFSETLOWER, -1, 0, floorValue);
                }
             });
             });
     }
     }

Bitte beachte, dass alle Beiträge zu Online-Soccer-Wiki von anderen Mitwirkenden bearbeitet, geändert oder gelöscht werden können. Reiche hier keine Texte ein, falls du nicht willst, dass diese ohne Einschränkung geändert werden können.

Du bestätigst hiermit auch, dass du diese Texte selbst geschrieben hast oder diese von einer gemeinfreien Quelle kopiert hast (weitere Einzelheiten unter Online-Soccer-Wiki:Urheberrechte). ÜBERTRAGE OHNE GENEHMIGUNG KEINE URHEBERRECHTLICH GESCHÜTZTEN INHALTE!

Abbrechen Bearbeitungshilfe (wird in einem neuen Fenster geöffnet)