Skip to content
  • Home
  • Recent
  • Tags
  • 0 Unread 0
  • Categories
  • Unreplied
  • Popular
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. [gelöst] - Learning JS - ein erster Versuch

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    17
    1
    3.4k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    1.1k

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.5k

[gelöst] - Learning JS - ein erster Versuch

Scheduled Pinned Locked Moved JavaScript
31 Posts 5 Posters 1.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • paul53P paul53

    @codierknecht
    Übrigens: Bei den Werten, die im ursprünglichen Thema zu sehen sind, darf man nicht mit parseInt() wandeln, sondern mit parseFloat().
    Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

    CodierknechtC Online
    CodierknechtC Online
    Codierknecht
    Developer Most Active
    wrote on last edited by
    #17

    @paul53 sagte in Learning JS - ein erster Versuch:

    @codierknecht
    Übrigens: Bei den Werten, die im ursprünglichen Thema zu sehen sind, darf man nicht mit parseInt() wandeln, sondern mit parseFloat().
    Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

    Natürlich … werde ich oben ändern.

    @paul53 sagte in Learning JS - ein erster Versuch:

    @codierknecht
    Übrigens: Bei den Werten, die im ursprünglichen Thema zu sehen sind, darf man nicht mit parseInt() wandeln, sondern mit parseFloat().
    Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

    Klingt auch etwas handlicher als mit Leerzeichen zu splitten.

    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

    Proxmox 9.1.1 LXC|8 GB|Core i7-6700
    HmIP|ZigBee|Tasmota|Unifi
    Zabbix Certified Specialist
    Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

    1 Reply Last reply
    0
    • paul53P paul53

      @codierknecht
      Übrigens: Bei den Werten, die im ursprünglichen Thema zu sehen sind, darf man nicht mit parseInt() wandeln, sondern mit parseFloat().
      Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

      CodierknechtC Online
      CodierknechtC Online
      Codierknecht
      Developer Most Active
      wrote on last edited by
      #18

      @paul53 sagte in Learning JS - ein erster Versuch:

      Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

      Auch das habe ich oben geändert.
      Damit ist das mit den Array-Indizes 1,2 und 3 schon fast so einfach, dass man das enum auch wieder weglassen könnte.
      Ich lasse es aber wegen Wart- und Erweiterbarkeit mal drin.

      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

      Proxmox 9.1.1 LXC|8 GB|Core i7-6700
      HmIP|ZigBee|Tasmota|Unifi
      Zabbix Certified Specialist
      Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

      CodierknechtC 1 Reply Last reply
      0
      • CodierknechtC Codierknecht

        @paul53 sagte in Learning JS - ein erster Versuch:

        Außerdem stehen die Werte laut Log immer hinter einem "):". Damit würde ich splitten.

        Auch das habe ich oben geändert.
        Damit ist das mit den Array-Indizes 1,2 und 3 schon fast so einfach, dass man das enum auch wieder weglassen könnte.
        Ich lasse es aber wegen Wart- und Erweiterbarkeit mal drin.

        CodierknechtC Online
        CodierknechtC Online
        Codierknecht
        Developer Most Active
        wrote on last edited by
        #19

        @codierknecht
        Aktueller Stand für heute im Eingangspost.
        Das Konvertieren und Prüfen der Werte habe ich in eine eigene Funktion ausgelagert.

        Für heute lasse ich das erstmal so stehen. Morgen ist auch noch ein Tag.

        Letzte Erkenntnis für heute:
        Für mehr als 2-3 Zeilen JS lohnt sich auf jeden Fall die Installation von VSCode.

        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

        Proxmox 9.1.1 LXC|8 GB|Core i7-6700
        HmIP|ZigBee|Tasmota|Unifi
        Zabbix Certified Specialist
        Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

        CodierknechtC 1 Reply Last reply
        0
        • CodierknechtC Codierknecht

          @codierknecht
          Aktueller Stand für heute im Eingangspost.
          Das Konvertieren und Prüfen der Werte habe ich in eine eigene Funktion ausgelagert.

          Für heute lasse ich das erstmal so stehen. Morgen ist auch noch ein Tag.

          Letzte Erkenntnis für heute:
          Für mehr als 2-3 Zeilen JS lohnt sich auf jeden Fall die Installation von VSCode.

          CodierknechtC Online
          CodierknechtC Online
          Codierknecht
          Developer Most Active
          wrote on last edited by
          #20

          @codierknecht
          Warum meckert VSCode hier?
          f347a38c-68df-48d0-b36a-071ec9ef02b8-image.png

          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

          Proxmox 9.1.1 LXC|8 GB|Core i7-6700
          HmIP|ZigBee|Tasmota|Unifi
          Zabbix Certified Specialist
          Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

          OliverIOO 1 Reply Last reply
          0
          • CodierknechtC Codierknecht

            @codierknecht
            Warum meckert VSCode hier?
            f347a38c-68df-48d0-b36a-071ec9ef02b8-image.png

            OliverIOO Offline
            OliverIOO Offline
            OliverIO
            wrote on last edited by OliverIO
            #21

            @codierknecht
            Es ist zwar ein separater Block aber evtl kollidiert diese error Deklaration mit der aus dem exec callback. Dort Ishtar man auch so ein kleines strichlein mit einem Hinweis.
            Was passiert wenn du das error aus dem catch Block bspw nach err umbenennst?

            Meine Adapter und Widgets
            TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
            Links im Profil

            CodierknechtC 1 Reply Last reply
            0
            • OliverIOO OliverIO

              @codierknecht
              Es ist zwar ein separater Block aber evtl kollidiert diese error Deklaration mit der aus dem exec callback. Dort Ishtar man auch so ein kleines strichlein mit einem Hinweis.
              Was passiert wenn du das error aus dem catch Block bspw nach err umbenennst?

              CodierknechtC Online
              CodierknechtC Online
              Codierknecht
              Developer Most Active
              wrote on last edited by Codierknecht
              #22

              @oliverio
              Den Verdacht hatte ich auch schon - hilft nix :-(
              Hab's dann wieder zu "error" zurück geändert, weil das so in fast allen Dokus verwendet wird.
              Der Scope ist ja auch ein völlig anderer als das "error" in der Callback.
              Es wird ja auch gemeckert, dass die gar nicht deklariert wäre. Dann müsste ich aber try-catch völlig falsch verstanden haben.

              Die 3 Punkte im Callback meckern nur an, dass hier keine Typdeklaration vorhanden ist.
              Da wir hier JS und kein TS haben, habe ich das mal geflissentlich ignoriert ;-)

              P.S.: Es meckert auch nur VSCode - im Editor im ioB sieht's OK aus

              "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

              Proxmox 9.1.1 LXC|8 GB|Core i7-6700
              HmIP|ZigBee|Tasmota|Unifi
              Zabbix Certified Specialist
              Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

              OliverIOO CodierknechtC 2 Replies Last reply
              0
              • CodierknechtC Codierknecht

                @oliverio
                Den Verdacht hatte ich auch schon - hilft nix :-(
                Hab's dann wieder zu "error" zurück geändert, weil das so in fast allen Dokus verwendet wird.
                Der Scope ist ja auch ein völlig anderer als das "error" in der Callback.
                Es wird ja auch gemeckert, dass die gar nicht deklariert wäre. Dann müsste ich aber try-catch völlig falsch verstanden haben.

                Die 3 Punkte im Callback meckern nur an, dass hier keine Typdeklaration vorhanden ist.
                Da wir hier JS und kein TS haben, habe ich das mal geflissentlich ignoriert ;-)

                P.S.: Es meckert auch nur VSCode - im Editor im ioB sieht's OK aus

                OliverIOO Offline
                OliverIOO Offline
                OliverIO
                wrote on last edited by
                #23

                @codierknecht

                Evtl gilt hier dies
                https://stackoverflow.com/questions/68240884/error-object-inside-catch-is-of-type-unknown

                Meine Adapter und Widgets
                TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                Links im Profil

                1 Reply Last reply
                0
                • CodierknechtC Codierknecht

                  @oliverio
                  Den Verdacht hatte ich auch schon - hilft nix :-(
                  Hab's dann wieder zu "error" zurück geändert, weil das so in fast allen Dokus verwendet wird.
                  Der Scope ist ja auch ein völlig anderer als das "error" in der Callback.
                  Es wird ja auch gemeckert, dass die gar nicht deklariert wäre. Dann müsste ich aber try-catch völlig falsch verstanden haben.

                  Die 3 Punkte im Callback meckern nur an, dass hier keine Typdeklaration vorhanden ist.
                  Da wir hier JS und kein TS haben, habe ich das mal geflissentlich ignoriert ;-)

                  P.S.: Es meckert auch nur VSCode - im Editor im ioB sieht's OK aus

                  CodierknechtC Online
                  CodierknechtC Online
                  Codierknecht
                  Developer Most Active
                  wrote on last edited by Codierknecht
                  #24

                  Jetzt habe ich das zum Testen mal im ioB laufen lassen.
                  Dabei stolpere ich über das valueArray.length.
                  Wenn die Zeile drin ist, bringt mit das Log ein "undefined".
                  Kommentiere ich das aus, läuft das Script wie gewünscht und schreibt auch die erwartbaren Werte in die DP.

                  fbd78e70-4d7d-4a5c-be25-36c1a59fcfae-image.png

                  Interessant: Das Error-Handling funktioniert wie erwartet. Alles tacko

                  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                  Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                  HmIP|ZigBee|Tasmota|Unifi
                  Zabbix Certified Specialist
                  Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                  OliverIOO 1 Reply Last reply
                  0
                  • CodierknechtC Codierknecht

                    Jetzt habe ich das zum Testen mal im ioB laufen lassen.
                    Dabei stolpere ich über das valueArray.length.
                    Wenn die Zeile drin ist, bringt mit das Log ein "undefined".
                    Kommentiere ich das aus, läuft das Script wie gewünscht und schreibt auch die erwartbaren Werte in die DP.

                    fbd78e70-4d7d-4a5c-be25-36c1a59fcfae-image.png

                    Interessant: Das Error-Handling funktioniert wie erwartet. Alles tacko

                    OliverIOO Offline
                    OliverIOO Offline
                    OliverIO
                    wrote on last edited by
                    #25

                    @codierknecht
                    kannst du bitte den source posten?

                    Meine Adapter und Widgets
                    TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                    Links im Profil

                    CodierknechtC 1 Reply Last reply
                    0
                    • OliverIOO OliverIO

                      @codierknecht
                      kannst du bitte den source posten?

                      CodierknechtC Online
                      CodierknechtC Online
                      Codierknecht
                      Developer Most Active
                      wrote on last edited by Codierknecht
                      #26

                      @oliverio Voilá

                      const execPython = 'python /opt/SunnyPortal/SunnyPortal.py 192.168.178.20';
                      const dpPrefix = '0_userdata.0.SunnyPortal.';
                      const arraySize = 6;
                      const position = {"watt": 1, "today": 2, "total": 3};
                      
                      createState(dpPrefix + 'Watt', 0, {name: 'Aktuelle Leistung', type: 'number', unit: 'W'});
                      createState(dpPrefix + 'Heute', 0, {name: 'Produziert heute', type: 'number', unit: 'kWh'});
                      createState(dpPrefix + 'Gesamt', 0, {name: 'Produziert gesamt', type: 'number', unit: 'kWh'});
                      
                      function parseValue(value) {
                        var result = parseFloat(value);
                        if (!isNaN(result)) {
                          return result;
                        } else {
                          throw 'Value <' + value + '> could not be converted';  
                        }
                      }
                      
                      function writeValues(watts, today, total) {
                        setState(dpPrefix + 'Watt', watts, true);
                        setState(dpPrefix + 'Heute', today, true);
                        setState(dpPrefix + 'Gesamt', total, true);
                      };
                      
                      function getData() {
                        try {
                      //    exec(execPython, function (error, result) {
                      //      if (!error) {
                      var result = 'X):100):150.55):200.88):Y):Z):blubb):blah';    
                              log(result);
                              var valueArray = result.split('):');
                              if (valueArray.length != 6) throw "Result does not match expected length";
                              writeValues(parseValue(valueArray[position.watt]), parseValue(valueArray[position.today]), parseValue(valueArray[position.total]));
                      //      } else {
                      //        throw error;
                      //      }
                      //    });
                        } catch(err) {
                          log('Error: ' + err.message);
                        }
                      }
                      
                      getData();
                      
                      //schedule('*/15 5-22 * * *', getData);
                      
                      

                      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                      Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                      HmIP|ZigBee|Tasmota|Unifi
                      Zabbix Certified Specialist
                      Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                      OliverIOO 1 Reply Last reply
                      0
                      • CodierknechtC Codierknecht

                        @oliverio Voilá

                        const execPython = 'python /opt/SunnyPortal/SunnyPortal.py 192.168.178.20';
                        const dpPrefix = '0_userdata.0.SunnyPortal.';
                        const arraySize = 6;
                        const position = {"watt": 1, "today": 2, "total": 3};
                        
                        createState(dpPrefix + 'Watt', 0, {name: 'Aktuelle Leistung', type: 'number', unit: 'W'});
                        createState(dpPrefix + 'Heute', 0, {name: 'Produziert heute', type: 'number', unit: 'kWh'});
                        createState(dpPrefix + 'Gesamt', 0, {name: 'Produziert gesamt', type: 'number', unit: 'kWh'});
                        
                        function parseValue(value) {
                          var result = parseFloat(value);
                          if (!isNaN(result)) {
                            return result;
                          } else {
                            throw 'Value <' + value + '> could not be converted';  
                          }
                        }
                        
                        function writeValues(watts, today, total) {
                          setState(dpPrefix + 'Watt', watts, true);
                          setState(dpPrefix + 'Heute', today, true);
                          setState(dpPrefix + 'Gesamt', total, true);
                        };
                        
                        function getData() {
                          try {
                        //    exec(execPython, function (error, result) {
                        //      if (!error) {
                        var result = 'X):100):150.55):200.88):Y):Z):blubb):blah';    
                                log(result);
                                var valueArray = result.split('):');
                                if (valueArray.length != 6) throw "Result does not match expected length";
                                writeValues(parseValue(valueArray[position.watt]), parseValue(valueArray[position.today]), parseValue(valueArray[position.total]));
                        //      } else {
                        //        throw error;
                        //      }
                        //    });
                          } catch(err) {
                            log('Error: ' + err.message);
                          }
                        }
                        
                        getData();
                        
                        //schedule('*/15 5-22 * * *', getData);
                        
                        

                        OliverIOO Offline
                        OliverIOO Offline
                        OliverIO
                        wrote on last edited by OliverIO
                        #27

                        @codierknecht sagte in Learning JS - ein erster Versuch:

                        Da du

                        throw "Result does not match expected length"
                        

                        machst wird an das catch auch nur der Text übergeben und nicht ein Error-Objekt.
                        Daher ist err.message undefined.
                        Korrekt wäre ein generisches Error-Objekt zu erzeugen

                        throw Error("Result does not match expected length")
                        

                        Dann klappt das auch mit dem Stacktrace bei der Fehlerausgabe, falls man den Fehler im catch den Fehler nach Prüfung dann doch rethrown möchte mit

                        throw error
                        

                        Meine Adapter und Widgets
                        TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
                        Links im Profil

                        CodierknechtC 1 Reply Last reply
                        1
                        • OliverIOO OliverIO

                          @codierknecht sagte in Learning JS - ein erster Versuch:

                          Da du

                          throw "Result does not match expected length"
                          

                          machst wird an das catch auch nur der Text übergeben und nicht ein Error-Objekt.
                          Daher ist err.message undefined.
                          Korrekt wäre ein generisches Error-Objekt zu erzeugen

                          throw Error("Result does not match expected length")
                          

                          Dann klappt das auch mit dem Stacktrace bei der Fehlerausgabe, falls man den Fehler im catch den Fehler nach Prüfung dann doch rethrown möchte mit

                          throw error
                          
                          CodierknechtC Online
                          CodierknechtC Online
                          Codierknecht
                          Developer Most Active
                          wrote on last edited by
                          #28

                          @oliverio
                          Danke - kaum macht man's richtig, klappt's auch.

                          Hab's im Eingangspost nachgezogen.

                          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                          Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                          HmIP|ZigBee|Tasmota|Unifi
                          Zabbix Certified Specialist
                          Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                          CodierknechtC 1 Reply Last reply
                          0
                          • CodierknechtC Codierknecht

                            @oliverio
                            Danke - kaum macht man's richtig, klappt's auch.

                            Hab's im Eingangspost nachgezogen.

                            CodierknechtC Online
                            CodierknechtC Online
                            Codierknecht
                            Developer Most Active
                            wrote on last edited by
                            #29

                            @codierknecht
                            Ich denke, mit dem aktuellen Ergebnis kann ich zufrieden sein.
                            "Da wirst'e alt wie 'ne Kuh und lernst immer noch dazu".

                            Und falls @jprisum-de hier mitliest:
                            Natürlich ist das Script jetzt deutlich umfangreicher als das ursprüngliche.
                            Hat aber einige entscheidende Vorteile:

                            • Es ist vor allem lesbarer! Es ist damit intuitiv verständlich und leichter zu warten und zu erweitern.
                            • Fehlerbehandlung: Mögliche Fehler werden abgefangen und mit
                              einer aussagekräftige Meldung im Log protokolliert.

                            Ich mach' dann hier mal zu ...

                            "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                            Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                            HmIP|ZigBee|Tasmota|Unifi
                            Zabbix Certified Specialist
                            Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                            HomoranH 1 Reply Last reply
                            0
                            • CodierknechtC Codierknecht

                              @codierknecht
                              Ich denke, mit dem aktuellen Ergebnis kann ich zufrieden sein.
                              "Da wirst'e alt wie 'ne Kuh und lernst immer noch dazu".

                              Und falls @jprisum-de hier mitliest:
                              Natürlich ist das Script jetzt deutlich umfangreicher als das ursprüngliche.
                              Hat aber einige entscheidende Vorteile:

                              • Es ist vor allem lesbarer! Es ist damit intuitiv verständlich und leichter zu warten und zu erweitern.
                              • Fehlerbehandlung: Mögliche Fehler werden abgefangen und mit
                                einer aussagekräftige Meldung im Log protokolliert.

                              Ich mach' dann hier mal zu ...

                              HomoranH Do not disturb
                              HomoranH Do not disturb
                              Homoran
                              Global Moderator Administrators
                              wrote on last edited by Homoran
                              #30

                              @codierknecht sagte in [gelöst] - Learning JS - ein erster Versuch:

                              Ich mach' dann hier mal zu ...

                              kannst du nicht :grin:

                              kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

                              Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

                              der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

                              CodierknechtC 1 Reply Last reply
                              0
                              • HomoranH Homoran

                                @codierknecht sagte in [gelöst] - Learning JS - ein erster Versuch:

                                Ich mach' dann hier mal zu ...

                                kannst du nicht :grin:

                                CodierknechtC Online
                                CodierknechtC Online
                                Codierknecht
                                Developer Most Active
                                wrote on last edited by
                                #31

                                @homoran
                                Achtung Goldwaagenalarm. Virtuell natürlich :joy:

                                "Any fool can write code that a computer can understand. Good programmers write code that humans can understand." (Martin Fowler, "Refactoring")

                                Proxmox 9.1.1 LXC|8 GB|Core i7-6700
                                HmIP|ZigBee|Tasmota|Unifi
                                Zabbix Certified Specialist
                                Konnte ich Dir helfen? Dann benutze bitte das Voting unten rechts im Beitrag

                                1 Reply Last reply
                                1
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                Support us

                                ioBroker
                                Community Adapters
                                Donate

                                539

                                Online

                                32.7k

                                Users

                                82.4k

                                Topics

                                1.3m

                                Posts
                                Community
                                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                                ioBroker Community 2014-2025
                                logo
                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Home
                                • Recent
                                • Tags
                                • Unread 0
                                • Categories
                                • Unreplied
                                • Popular
                                • GitHub
                                • Docu
                                • Hilfe