Präsentation Bewerbung Präsentation

Hallo, mein Name ist Dmitry Karlovsky und ich spreche manchmal auf Konferenzen, Tagungen und vor kurzem bin ich selbst Mitglied des Organisationsteams eines von ihnen - PiterJS . Vor kurzem hatten wir ein Jubiläum - 40 Treffen. Aber anstatt uns zu entspannen und Glückwünsche zu erhalten, wurden wir müde und bereiteten selbst Berichte der Organisatoren vor .


Testen der Sprachsteuerung


Dies reicht uns jedoch nicht aus. Deshalb haben wir beschlossen, das große Jubiläum mit einer Konferenz am Ufer der Newa PiterJSConf zu feiern , die an diesem Samstag, dem 7. September 2019, stattfinden wird. Beeilen Sie sich , sich anzumelden , solange noch Plätze frei sind, da die Teilnahme daran für Sie völlig kostenlos ist.


Wir tun dies alles nicht für Geld, sondern für die großartige Idee, dass Wissen frei sein sollte. Daher ist alles, was wir tun , in Open Source verfügbar . Wir freuen uns, unsere Best Practices, Kenntnisse und Erfahrungen mit anderen zu teilen. Wir fordern die Zusammenarbeit von Organisatoren aus anderen Städten dringend auf, eine offene Plattform für die regelmäßige Organisation von Technologietreffen zu schaffen. Begleiten Sie uns als Organisator , Partner , Redner , Freiwilliger , Förderer oder einfach nur als Zuhörer.


In der Zwischenzeit biete ich Ihnen eine Geschichte über die Präsentationswebanwendung $hyoo_slides , die ich für alle meine Präsentationen verwende. Videoaufnahmen sind auf YouTube verfügbar , aber nicht alles ist vorhanden. Sie können diese Geschichte als Artikel lesen oder in der Benutzeroberfläche der Anwendung selbst öffnen . Als nächstes werde ich Ihnen sagen, wie viel es kann und wie es funktioniert.


Listener-Schnittstelle


Präsentation hören


Hier ist die Oberfläche, die das Publikum während der Aufführung sieht. Darin ist nichts überflüssig.


Der Name und die Nummer der Folie werden oben angezeigt. Zuhörer können Fragen haben. Wenn sie diese Nummer schnell aufzeichnen, können sie sie nach der Rede benennen und so das Publikum vor langwierigem Warten bewahren, wenn der Sprecher eine Folie findet, auf der die Frage gestellt wird.


Unten können Sie auf den Fortschrittsbalken achten, der den späten Zuhörern anzeigt, wie viel sie verpasst haben. Und allen anderen - wie viel bleibt bis zum Ende übrig. Sie wird nicht anhand der Anzahl der Folien berechnet, sondern anhand der Lautstärke der erzählten Rede.


Schau wie ich kann


Die Grundidee ist, den Sprecher auf den Inhalt konzentrieren zu lassen und sich nicht um das Design zu kümmern. Der Bericht benötigt überhaupt keine besonderen Schönheiten und spektakulären Animationen. Andernfalls wird das Design auf sich aufmerksam machen. Und der Inhalt läuft Gefahr, an den Ohren vorbei zu fliegen.


Weil ich Batman bin!


Das Design sollte dennoch ordentlich sein, um den Eindruck des Berichts nicht zu beeinträchtigen. Daher ist die Gestaltung des Antrags einfach, nicht eingängig und steht vor allem im Einklang mit den Empfehlungen der Programmausschüsse.


Lautsprecherschnittstelle


Die Schnittstelle des Lautsprechers ist in zwei Teile unterteilt.


Präsentationspräsentation


Links sehen die Zuhörer. Und rechts sind die Notizen des Sprechers. Sie werden Ihnen helfen, sich an einen verlorenen Gedanken zu erinnern, ohne sich vom Publikum abzuwenden und ohne sie für eine lange ... ähm ... diese ... Pause zu belasten.


Die Hauptsache ist zufrieden


Daher wird in unserem Fall der Inhalt als Artikel im MarkDown- Format geschrieben und auf einigen GitHub-Seiten angeordnet. Und die Webanwendung kümmert sich um den Rest.


 #       #       

Nach der Rede wird das Textprotokoll des Berichts häufig in Form eines Artikels über einige Habré angelegt . Sie können es für einen Monat, zwei, ein halbes Jahr tun. Die Aufgabe ist eine undankbare Übersetzung von Sprache in Text. Da die Quelle der Folien jedoch bereits im Markdown-Format vorliegt und die Kommentare des Sprechers enthält, können sie sofort in dieser Form veröffentlicht werden.


Textstile


Nur-Text wird nur dem Präsentator angezeigt. Und alle Arten von Bildern, Listen, Tabellen, Zitaten usw. sind für alle sichtbar.


 - ** - ** ** - ~~~~ - `````` 

  • Akzent
  • Starker Akzent
  • Löschen

Natürlich stehen verschiedene Inline-Formatierungswerkzeuge zur Verfügung.


Quellcode


Natürlich werden auch Quellcodeblöcke unterstützt, die in allen Farben des Regenbogens gemalt sind. Genau wie du magst.


 ```javascript const hello = ()=> <body> Hello, "world"! </body> ``` 

 const hello = ()=> <body> Hello, "world"! </body> 

Tabellen


Der Vergleich verschiedener Dinge hilft Ihnen Tabellen. Lassen Sie uns zum Beispiel sehen, warum $hyoo_slides besser ist als seine engsten Konkurrenten - shwr.me und Google Slides


 | | shwr.me | google slides | slides.hyoo.ru | |--------------------------|---------|---------------|----------------| |   MarkDown | - | - | + | |   | - | + | + | |   | - | - | + | |  | - | + | + | 

shwr.meGoogle Slidesslide.hyoo.ru
Quelle in MarkDown- -- -+
Dual Panel-Modus- -++
Automatischer Schiebeschalter- -- -+
Offline- -++

Wie Sie sehen können, schlägt $hyoo_slides Konkurrenz an allen Fronten. Mit Ausnahme derjenigen, die nicht in der Tabelle enthalten sind, natürlich.


Nun, Lano, Tische sind langweilig.


Bilder


Halte die Katze.


 ![](https://github.com/nin-jin/slides/raw/master/slides/cat.gif) 

Cat


Beachten Sie, dass der Hintergrund der Folien leicht grau ist. Daher ist es besser, Bilder nicht auf weißem Hintergrund, sondern mit Transparenz vorzubereiten, damit sich um die Bilder kein unangenehmes weißes Rechteck befindet. Dies geschieht so, dass die weißen Bereiche kontrastreich aussehen und nicht mit dem Hintergrund verschmelzen.


Video


Sie können Videos, Webseiten und andere externe Inhalte mit derselben MarkDown-Syntax wie beim Einfügen von Bildern veröffentlichen.


 ![ ](https://www.youtube.com/embed/exfBX2pb7AQ?autoplay=1) 

Zielgruppe


Zum Beispiel habe ich ein Video eingefügt, das zeigt, dass moderne Schnittstellen so einfach und bequem sind, dass sogar ein Affe damit umgehen kann.


Tastaturnavigation


Sie können Folien mit Pfeilen auf der Tastatur wechseln. Um jedoch nicht am Laptop befestigt zu werden, sondern frei auf der Bühne herumlaufen zu können, benötigen Sie ein Radio-Verlängerungskabel für Ihren Finger. Er ist ein Clicker.


Pfeile


Aber was ist, wenn der Clicker kaputt ist?


Codephrasen


Sie denken wahrscheinlich, dass ich in dem Raum irgendwo einen misshandelten Kosaken habe, der anstelle von mir die Folien wechselt? Dies ist jedoch nicht so.


  • Weiter bitte.
  • Zurück bitte.
  • Folie Nummer 5, sei freundlich.
  • Am Anfang bitte.
  • Am Ende bitte.
  • Finde die "Katze", sei freundlich.
  • Wiederholen Sie bitte.
  • Halt die Klappe , sei nett.
  • Bitte fahren Sie fort .
  • Schalten Sie bitte das Licht aus .

Wiederholen Sie bitte. Eine Stimme von oben wiederholt den letzten Satz.


Ja, Folien können die Stimme vollständig steuern und Ihre Hände für Gesten frei lassen. Es verwendet eine Standard-Web-API für die Spracherkennung und -synthese.


Das zehnmalige Wiederholen dieser $hyoo_slides ist jedoch langweilig, sodass $hyoo_slides Sprechernotizen analysieren und die Folie automatisch wechseln kann, wenn Sie das letzte Wort sagen.


Fingergesten


Okay, die Situation wird komplizierter. Jemand, der Ihre Rede gehört hatte, beschloss, Ihre Folien vom Tablet aus zu sehen, während er mit der U-Bahn nach Hause fuhr.


Gesten


Es gibt keine Tastatur. Die Züge sind laut. Hier kommen gewöhnliche Fingergesten zur Rettung.


Offline


Aber dann ruft er in den Tunnel und seine Verbindung verschwindet.


Kein netzwerk


Es spielt keine Rolle, wir haben die progressive Web2.0 HTML5-Webanwendung mit voller Funktionalität, auch wenn kein Internet vorhanden ist.


PDF-Druck


Aber hier kommen die Organisatoren auf Sie zu und sagen: "Wir wollen ein PDF."


Impressionum


Welches PDF? Wir haben hier die multimediale interaktive Web2.0 HTML5 Progressive Webanwendung. Sie erklären Ihnen jedoch, dass die Anwendung heute und morgen nicht mehr vorhanden ist. Und wenn ja, will er Geld. Und wenn Sie nicht möchten, können die Folien dort bereits bis zur Unkenntlichkeit geändert werden. Und das PDF befindet sich leise im Archiv mit genau dem Inhalt, der dem während der Aufführung aufgenommenen Video entspricht.


Nun, es spielt keine Rolle, drücken Sie Ctrl+P , wählen Sie "In PDF drucken" und holen Sie sich das, was Sie brauchen. Dies geschieht einfach - das Ereignis onbeforeprint wird onbeforeprint und wenn es auftritt, werden anstelle nur der aktuellen Folie alle Folien gerendert. Und auf einem onafterprint , mit onafterprint des aktuellen, werden die Folien gelöscht.


Damit sind die Feature-Listen nun beendet.


So erstellen Sie eine Präsentation


Das $hyoo_slides ist einfach. Sie benötigen readme.md mit Ihren Inhalten und Bildern. Ebenfalls in der Nähe müssen Sie index.html kopieren und einfügen, wodurch zur Webanwendung weitergeleitet und Ihre Präsentation darin geöffnet wird. Und auch offline.js für die Offline-Unterstützung.



Beachten Sie, dass diese index.html der Anwendung alle Dateien enthält, auf die über die Domäne index.html werden kann, in der Sie das Ganze abgelegt haben. GitHub Pages ist eine sehr bequeme und sichere Option. Ich benutze es selbst.


Andere Anwendungen


Wenn Ihnen diese Anwendung gefallen hat, können Sie sich andere interessante Anwendungen ansehen, die im $ mol-Framework implementiert sind. Sie sind so leicht, dass selbst ein paar Dutzend keine Angst haben, sie alle auf einmal auf eine Folie zu laden.


Anwendungsgalerie


Aber irgendwie später über sie ...


Präsentationsbeispiele


Weitere Informationen zum Framework finden Sie in einer separaten Präsentation. Sie können tiefer in eine Präsentation über die PPR eintauchen. Und Sie können den Vorhang der Zukunft in einer Präsentation zur Quantisierung von Berechnungen aufheben.



Sie alle verwenden $ hyoo_slides zum Anzeigen. Ich hoffe, dass es bald mehr solche Präsentationen geben wird.


Anwendungsstruktur


Lassen Sie uns jetzt die Motorhaube ein wenig öffnen und sehen, wie die Anwendung angeordnet ist und wie Sie dies in nur einem Abend tun können.


 $hyoo_slides_page $mol_view sub / <= Listener <= Speaker 

 export class $hyoo_slides_page extends $mol_view { sub() { return [ this.Listener() , this.Speaker() , ] } } 

Hier finden Sie eine Beschreibung eines einzelnen Bildschirms auf oberster Ebene in view.tree und den entsprechenden TypeScript-Code. Hier deklarieren wir die Komponente $hyoo_slides_page , die die Basiskomponente $mol_view . Diese Komponente hat eine sub . Alles, was diese Eigenschaft zurückgibt, wird innerhalb der Komponente gerendert. Daher definieren wir es neu und übergeben als Wert ein Array aus zwei Elementen: Listener - eine Komponente zur Ausgabe einer Folie an Listener und Speaker - eine Komponente eines zusätzlichen Lautsprecherfelds.


Seitenlayout wechseln


Zusätzlich zur Beschreibung der Struktur können wir auch eine Programmlogik anwenden, mit der beliebige Eigenschaften dynamisch berechnet werden können.


 sub() { const role = this.role() return [ this.Listener() , ... ( role === 'speaker' ) ? [ this.Speaker() ] : [] , ] } 

Hier ist die Logik einfach: Wir zeigen immer Folien für Hörer an, aber das Lautsprecherfeld wird nur angezeigt, wenn die aktuelle Rolle speaker . Wenn sich die Rolle ändert, ändert sich auch das Layout der Anwendung aufgrund der Magie der objektreaktiven Programmierung.


Routing


Wir werden die Rolle vom $mol_state_arg über die spezielle reaktive API $mol_state_arg .


 role() : 'speaker' | 'listener' { return $mol_state_arg.value( 'role' ) || 'speaker' } 

Aus irgendeinem Grund hat sich die Adresse geändert - die Rolle wird automatisch daraus extrahiert und an diese Methode weitergeleitet.


Struktur der Listener-Schnittstelle


Beschreiben wir die Listener-Oberfläche.


 Listener $mol_page title <= title tools / <= Slide_switcher body / <= Listener_content <= Progress 

Es wird die Standardkomponente $mol_page die eine typische Seite mit einem Header und einem Body zeichnet. In der Kopfzeile befindet sich ein Bereich, in dem der Seitenname angezeigt wird. Über die title Eigenschaft können Sie angeben, was dort ausgegeben werden soll. Was wir getan haben, indem wir die Titeleigenschaft mit unserer gleichnamigen Eigenschaft verknüpft haben. Wenn wir nun unser Eigentum ändern, haben wir die volle Kontrolle darüber, was auf der Seite als Titel angezeigt wird.


Rechts in der Kopfzeile befindet sich ein Ausgabebereich für zusätzliche Werkzeuge - tools . Darin geben wir Slides_switcher - eine Komponente zum Anzeigen der Slides_switcher und zum Umschalten zwischen benachbarten Folien.


Und schließlich zeigen wir als Seitenkörper in body den Inhalt der Folie und den Fortschrittsbalken an.


Seitenwechselstruktur


Wie implementiere Slide_switcher ? Verwenden Sie einfach die Standardkomponente $mol_paginator .


 Slide_switcher $mol_paginator value?val <=> slide?val 

Er hat lediglich einen veränderlichen Eigenschaftswert, den wir bilateral mit unserer Eigenschaft verknüpfen, die die Nummer der aktuellen Folie enthält. Keine Importe, Rückrufe, Ereignisse und sonstiger Papierkorb. Diese beiden Zeilen sind alles, was erforderlich ist, damit ein Arbeitsseitenwechsel auf Ihrer Seite angezeigt wird.


Inhaltsstruktur schieben


Um den Inhalt der Folie anzuzeigen, verwenden wir wieder die Standardkomponente $mol_text .


 Listener_content $mol_text uri_base <= uri_base text <= listener_content 

Es nimmt markdown und rendert ihn. Da sich die Links in diesem Text auf die Quelldatei und nicht auf unsere Anwendung beziehen, übergeben wir den Link an die Eigenschaft uri_base, in Bezug auf die alle Pfade aufgelöst werden.


Struktur der Fortschrittsanzeige


Wie Sie wahrscheinlich bereits vermutet haben, gibt es auch eine Standardkomponente für die Anzeige des Fortschritts - $mol_portion .


 Progress $mol_portion portion <= progress 

 portion: [ 0 .. 1 ] 

Wir geben ihm eine Zahl von 0 bis 1 und lassen einen Indikator für diese Aktie ausfüllen.


Struktur der Lautsprecherschnittstelle


Wir haben etwas Interessanteres in der Benutzeroberfläche des Sprechers. Die in der Kopfzeile angezeigten Werkzeuge sind in keiner Weise an die aktuelle Seite angehängt - sie gelten für die gesamte Anwendung. Anstatt sie hier fest zu codieren, platzieren wir daher nur den speaker_tools Slot, durch den wir die Liste der Komponenten von außen übertragen.


 Speaker $mol_page head <= speaker_tools /$mol_view body / <= Speaker_content 

Anwendungsstruktur


Gehen Sie nun eine Ebene $hyoo_slides und erstellen Sie eine Anwendungskomponente $hyoo_slides , die die Seitenkomponente verwendet.


 $hyoo_slides $mol_view Page!index $hyoo_slides_page - ... plugins / <= Nav <= Touch <= Speech_next - ... 

Jede $mol_view Komponente verfügt über eine plugins Eigenschaft, über die zusätzliche Logik mit ihr verbunden werden kann. Plugin-Plugins befinden sich auf demselben DOM-Knoten wie die Komponente selbst. Die Komponente initiiert sie während des Renderns. Und wenn ungefähr nicht mehr gerendert wird, werden Plugins automatisch zerstört.


Wir haben auch die Page Eigenschaft angekündigt, die für jeden Index eine separate Instanz der zuvor entwickelten Komponente $hyoo_slides_page .


Einrichtung externer Seiten


 Page!index $hyoo_slides_page role <= role slide?val <=> page_slide!index?val speaker_tools / <= Speech_toggle <= Speech_text <= Open_listener 

Wir übergeben die role unverändert an die Unterkomponente. Die page_slide der Seitenkomponente ist durch page_slide Kommunikation mit der Eigenschaft page_slide der Anwendung verbunden. Beachten Sie, dass page_slide nicht nur den optionalen neuen Wert, sondern auch den page_slide akzeptiert. Auf diese Weise können Sie für jede Seite eine Nummer zurückgeben. Schließlich haben wir in den zuvor speaker_tools Slot " speaker_tools drei Komponenten speaker_tools , um die Verwaltung der Folien zu speaker_tools .


Struktur des Sprachsteuerungsschalters


Wir implementieren Speech_toggle über die Standardkomponente $mol_check_icon , die ein Symbol zeichnet. Wenn Sie darauf klicken, wird das markierte Flag umgeschaltet. Der aktuelle Status wird durch Ändern der Farbe des Symbols angezeigt.


 Speech_toggle $mol_check_icon Icon <= Speech_toggle_icon $mol_icon_microphone checked?flag <=> speech_enabled?flag 

Wir haben das Symbol aus dem $mol_icon , in dem aus 4000 $mol_icon , die im asketischen Materialdesignstil hergestellt wurden, leicht das richtige zu finden ist.


Struktur der Schaltfläche zum Öffnen des Slave-Fensters


Hier ist alles einfach. Diese Schaltfläche ist der Link $mol_link . Sie kann die uri Eigenschaft mit einer Adresse festlegen oder etwas schlaueres tun und einfach die aktuelle Adresse patchen, indem sie einige Parameter durch arg .


 Listener_open $mol_link target \_blank arg * role \listener slide null sub / <= Listener_open_icon $mol_icon_external 

Hier haben wir die Foliennummer aus der Adresse gelöscht, damit das Slave-Fenster sie aus dem lokalen Speicher und nicht aus der Adresse entnimmt. Dadurch wird sichergestellt, dass die Fenster miteinander synchronisiert werden. Sie wiesen auch darauf hin, dass die Rolle ein „Zuhörer“ sein sollte. Innerhalb des Links setzen wir ein Symbol anstelle von Text.


Plugins


Plugins können die Funktionen der Komponente erheblich erweitern. Wir werden sie maximal nutzen.


 plugins / <= Nav <= Touch <= Speech_next <= Speech_prev <= Speech_start <= Speech_end - ... 

Alle von uns verwendeten Plugins können in drei Kategorien unterteilt werden: Tastaturnavigation, Gestensteuerung und Sprachsteuerung.


Tastaturnavigation


Mit $mol_nav es einfach, die Tastaturnavigation sowohl vertikal als auch horizontal zu implementieren. Alles, was benötigt wird, ist, dem Plug-In eine Liste von Schlüsseln zur Verfügung zu stellen, mit denen es umschaltet, und eine bidirektionale Kommunikation mit dem aktuellen Wert.


 Nav $mol_nav keys_y <= slide_keys keys_x <= slide_keys current_y?val <=> slide?val current_x?val <=> slide?val 

 slide_keys: [ 0 , 1 , 2 , 3 , ... , 30 ] ^ slide 

Fingergesten


Für die Fingerverfolgung gibt es ein $mol_touch . Mit ihm können Sie zoomen, schwenken und wischen. Es ist die letzte Gelegenheit, die uns jetzt interessiert.


 Touch $mol_touch swipe_to_left?event <=> go_next?event swipe_to_right?event <=> go_prev?event 

 go_next( event? : Event ) { this.slide( this.slide() + 1 ) } 

Es gibt zwei Arten von Wischen. Wischen Sie beispielsweise von einem beliebigen Teil des Bildschirms nach links oder rechts und wischen Sie aufgrund des rechten oder linken Bildschirmrandes zur Mitte. Im vorgestellten Code haben wir unsere Handler an die erste Art von Swipe gehängt.


Sprachsteuerung


Verwenden Sie zur $mol_speech . Für jede Version der Aktion muss eine Instanz des Plugins erstellt werden.


 Sing $mol_speech event_catch?val <=> sing?val patterns / \sing( \S+?)* \( \S+?)* 

Das Plugin akzeptiert einen Aktionshandler und eine Reihe von Mustern, bei deren Erkennung ein Ereignis ausgelöst wird. Sie können Erfassungsklammern in den Mustern verwenden, um die Wörter zu erhalten, die ihrem Inhalt im Handler entsprechen.


Automatischer Schiebeschalter


Standardmäßig erfordert $mol_speech eine höfliche Behandlung. Zum Beispiel sollten Sie nicht "singen" sagen, sondern "singen, bitte". Sie können die suffix Eigenschaft überschreiben, um dieses Codewort insgesamt zu ändern oder zu entfernen.


 Speech_next_auto $mol_speech event_catch?val <=> go_next?val suffix \ patterns <= speech_next_auto_patterns 

Zum Beispiel benötigen wir keine magischen Wörter, um die automatische Folienumschaltung zu implementieren. Wir werden jedoch dynamisch eine Reihe von Mustern generieren, die auf der Analyse des Inhalts des Sprechertextes basieren.


Anwendungsstart


Mit einer Anwendungskomponente können Sie sie wie jede normale Klasse manuell instanziieren. Wir werden jedoch den automatischen Start über das spezielle Attribut mol_view_root .


 <body mol_view_root="$hyoo_slides"> <script src="web.js" charset="utf-8"></script> </body> 

Der Attributname ist der Name der Komponente. Das Rendern auf diese Weise kann natürlich absolut jede Komponente sein.


Offline


Um Offline-Unterstützung hinzuzufügen, fügen Sie einfach das mol/offline/install Modul in das Bundle ein.


 include \/mol/offline/install 

Es wird automatisch ein ServiceWorker ausgelöst, der alle Anforderungen zwischenspeichert. Wenn das Netzwerk nicht verfügbar ist, werden Daten aus dem Cache zurückgegeben. Dies ist nicht die coolste Implementierung, aber für einfache Fälle, in denen Sie sich nicht darum kümmern möchten, reicht dies aus.


Druckmodus


Vorhin habe ich gesagt, dass Sie während des Druckens alle Seiten rendern müssen, aber es ist nicht erforderlich, onbeforeprint und onafterprint manuell zu überwachen, da wir über eine vollständig reaktive Programmierung verfügen. onafterprint wir den reaktiven Status $mol_print , der uns ein reaktives Flag gibt, auf das wir $mol_print können Rendering binden.


 sub() { if( !this.$.$mol_print.active() ) { return [ this.Page( this.slide() ) ] } return $mol_range2( index => this.Page( index ) , ()=> this.slide_keys().length , ) } 

Hier geben wir nur eine Seite zurück, wenn das active Flag nicht gesetzt ist. Andernfalls geben wir ein Lazy Array zurück, das seine Länge und Elemente gemäß den angegebenen Formeln berechnet.


Nachwort


Als Ergebnis haben wir eine moderne Webanwendung mit einer Reihe von Funktionen und einem Gewicht von nur 35 KB erhalten. Wenn Sie ein Manifest hinzufügen, wird eine vollwertige progressive Webanwendung angezeigt. Natürlich wurden viele Details nicht berücksichtigt. Sie können sie im Code auf dem Github sehen. Schreiben Sie bei allen Fragen Telegramme im Chat.


Diese Folien befinden sich in der App: slide.hyoo.ru
Anwendungsquellen: hyoo-ru / slide.hyoo.ru
Präsentationsbeispiele: Nin-Jin / Folien
Telegramm-Chat: @mam_mol

Ich würde mich freuen, wenn Sie versuchen, Ihre Präsentation mit $hyoo_slides zu machen. Und ich würde mich sehr freuen, wenn Sie dazu beitragen, dass es noch besser wird als jetzt. Vielen Dank für Ihre Aufmerksamkeit!

Source: https://habr.com/ru/post/de465763/


All Articles