initial commit, add Publish, add minimal theme, add content

This commit is contained in:
Felix Förtsch
2024-03-24 20:24:51 +01:00
commit cd2f440141
1240 changed files with 194709 additions and 0 deletions
@@ -0,0 +1,10 @@
---
layout: default
title: "404: Page not found"
permalink: 404.html
---
<div class="page">
<h1 class="page-title">404: Page not found</h1>
<p class="lead">Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. <a href="{{ "/" | relative_url }}">Head back home</a> to try finding it again.</p>
</div>
@@ -0,0 +1 @@
felixfoertsch.de
@@ -0,0 +1,8 @@
source "https://rubygems.org"
gem "bundler"
gem "jekyll"
gem "jekyll-gist"
gem "jekyll-paginate"
gem "jekyll-feed"
gem "jekyll-github-metadata"
gem "jekyll-octicons"
@@ -0,0 +1,103 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
colorator (1.1.0)
concurrent-ruby (1.2.3)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
faraday-net_http (3.1.0)
net-http
ffi (1.16.3)
forwardable-extended (2.6.0)
google-protobuf (4.26.0-arm64-darwin)
rake (>= 13)
http_parser.rb (0.8.0)
i18n (1.14.4)
concurrent-ruby (~> 1.0)
jekyll (4.3.3)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 1.0)
jekyll-sass-converter (>= 2.0, < 4.0)
jekyll-watch (~> 2.0)
kramdown (~> 2.3, >= 2.3.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (>= 0.3.6, < 0.5)
pathutil (~> 0.9)
rouge (>= 3.0, < 5.0)
safe_yaml (~> 1.0)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.16.1)
jekyll (>= 3.4, < 5.0)
octokit (>= 4, < 7, != 4.4.0)
jekyll-octicons (19.8.0)
jekyll (>= 3.6, < 5.0)
octicons (= 19.8.0)
jekyll-paginate (1.1.0)
jekyll-sass-converter (3.0.0)
sass-embedded (~> 1.54)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
net-http (0.4.1)
uri
octicons (19.8.0)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (5.0.4)
rake (13.1.0)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.6)
rouge (4.2.0)
safe_yaml (1.0.5)
sass-embedded (1.72.0-arm64-darwin)
google-protobuf (>= 3.25, < 5.0)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.5.0)
uri (0.13.0)
webrick (1.8.1)
PLATFORMS
arm64-darwin-23
DEPENDENCIES
bundler
jekyll
jekyll-feed
jekyll-gist
jekyll-github-metadata
jekyll-octicons
jekyll-paginate
BUNDLED WITH
2.4.10
@@ -0,0 +1,11 @@
# Released under MIT License
Copyright (c) 2013 Mark Otto.
Copyright (c) 2017 Andrew Fong.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
# felixfoertsch.de
This is my personal website.
@@ -0,0 +1,65 @@
# Dependencies
markdown: kramdown
highlighter: rouge
kramdown:
input: GFM
hard_wrap: false
syntax_highlighter: rouge
extensions: fenced_code_blocks
# Setup
title: felixfoertsch.de
tagline: "🚀 Rocketing along."
version: 18
description: ""
url: https://felixfoertsch.github.io
baseurl: # the optional subpath of your site, e.g. "/blog"
author:
name: "Felix Förtsch"
url: felixfoertsch.de
flair: ""
github:
profile: "https://github.com/felixfoertsch"
twitter:
profile: "https://twitter.com/felixfoertsch"
plugins:
- jekyll-feed
- jekyll-gist
- jekyll-paginate
- jekyll-octicons
- jekyll-github-metadata
include:
- keybase.txt
exclude:
- Gemfile
- Gemfile.lock
- jekyll-theme-hydeout.gemspec
- LICENSE.md
- Makefile
- package.json
- README.md
- .gitignore
sass:
style: compact # possible values: nested expanded compact compressed
defaults:
scope:
path: "_posts"
type: "posts"
values:
excerpt_separator: <!--more-->
layout: post
permalink: /:year/:month/:day/:title.html
paginate: 10
paginate_path: "/page:num" # Or '/blog/page:num' if you want to move your index pages
# Sidebar link settings
sidebar_home_link: true
@@ -0,0 +1,255 @@
---
layout: post
title: "Stephen Coveys sieben Wege zur Effektivitaet"
categories:
- Personal
tags:
- German
last_modified_at:
excerpt_separator: <!-- more -->
---
Die übergreifende Botschaft des Buchs lautet:
Wahre Effektivität bedeutet, sich darüber klar zu werden, was man erreichen möchte und diese Ziele proaktiv in die Tat umzusetzen. Dabei fährt man am besten, indem man Synergien mit anderen anstrebt, in dauerhafte Beziehungen investiert und auf ein ausgeglichenes Leben achtet.
<!-- more -->
In diesem Paket wurden folgende Fragen beantwortet:
Wie kann man sich dauerhaft verändern und langfristig leistungsfähig bleiben?
Wer sich verändern will, sollte nicht an seinem Verhalten arbeiten, sondern am Charakter.
Am eigenen Charakter zu arbeiten, bedeutet, persönliche Paradigmen an universellen Prinzipien auszurichten.
Wer dauerhaft sägen will, muss regelmäßig seine Säge schärfen.
Wie kann man Großes erreichen und effektiv seine Umwelt gestalten?
Jeder Mensch kann proaktiv sein und sein Schicksal selbst in die Hand nehmen.
Wer wirklich Bedeutungsvolles erreichen will, der braucht langfristige Ziele und ein Leitbild.
Um seine Ziele zu erreichen, sollte man das Ergebnis jeder Handlung möglichst bildlich vorwegnehmen.
Wer effektiv sein will, der sollte immer unter der Maßgabe „Wichtiges zuerst“ handeln.
Wie interagiert man effektiv mit anderen und schafft Synergien?
Wer „Win/Win” denkt, bekommt sein Stück vom Kuchen und gleichzeitig langfristige Beziehungen zu anderen.
Um stabile Beziehungen zu anderen zu führen, müssen emotionale Bankkonten gepflegt werden.
Wer Einfluss auf andere nehmen will, sollte lernen, ein empathischer Zuhörer zu werden.
Synergien entstehen, wenn Gruppenmitglieder einander mit Offenheit und Respekt begegnen.
---
#Wer sich verändern will, sollte nicht an seinem Verhalten arbeiten, sondern am Charakter.
Es gibt zwei Arten, an sich zu arbeiten und das eigene Leben zu verändern.
Entweder setzt man bei den Fähigkeiten und Fertigkeiten an, die das eigene Verhalten ausmachen, z.B. indem man Techniken für bessere Kommunikation oder Zeitmanagement erlernt.
Oder man setzt eine Ebene tiefer an und arbeitet am eigenen Charakter, den **grundlegenden Gewohnheiten und Glaubenssätzen**, mit denen man auf die Welt sieht.
Der erste Zugang sucht im Grunde nach einer Abkürzung zum Erfolg: reich werden, ohne dafür zu arbeiten; persönliches Wachstum ohne echte Entwicklung.
Doch persönliches Wachstum lässt sich nicht über Abkürzungen erreichen. Auf dem Weg zu wahrer Effektivität kann kein Schritt in der Entwicklung ausgelassen werden.
Das gilt für Fähigkeiten wie das Tennis- oder Klavierspiel und ebenso für die emotionale und charakterliche Entwicklung eines Menschen.
Wer sich wirklich verändern möchte, muss dies „**von innen nach außen**“ tun. Nur wer sich selbst drastisch verändert, kann auch seine Welt drastisch verändern. Wer z.B. eine glückliche Ehe führen will, muss erst selbst ein positiverer Mensch werden.
Wer als vertrauenswürdig wahrgenommen werden will, sollte nicht an seinen Kommunikationsfähigkeiten arbeiten, sondern daran, ein **vertrauenswürdigerer Mensch** zu werden.
Anstatt an der Oberfläche zu kratzen, sollte man **im Innern ansetzen**.
##Wer sich verändern will, sollte nicht an seinem Verhalten arbeiten, sondern am Charakter.
#Am eigenen Charakter zu arbeiten, bedeutet, persönliche Paradigmen an universellen Prinzipien auszurichten.
**Paradigmen** sind die **Bausteine unseres Charakters**. Sie sind die **Grundüberzeugungen**, die wir in uns tragen, die Brillen, mit denen wir auf die Welt sehen.
**Was wir wahrnehmen**, ist keine objektive Realität, sondern eine **subjektive Interpretation**, die durch unsere Paradigmen-Brillen eingefärbt ist.
Die **Gewohnheiten**, die den Großteil unseres Handelns ausmachen, **sind direkte Resultate unserer Paradigmen**.
Paradigmen, als Kern unseres Charakters, sind der Schlüssel jeder Veränderung. Wenn wir uns selbst verändern wollen, müssen wir unsere Grundüberzeugungen verändern. Dadurch verändern wir unsere subjektiven Realitäten und damit auch unser Verhalten.
Dazu ist es jedoch nötig, sich **der eigenen Paradigmen bewusst zu sein**. Wer grundlegende Gewohnheiten wie Prokrastination, Egoismus oder Ungeduld überwinden will, muss sich erst klar darüber werden, aus welchen Grundüberzeugungen diese Gewohnheiten folgen.
Für wahre Effektivität ist es sinnvoll, seine **persönlichen Paradigmen mit größeren, universellen Prinzipien in Einklang zu bringen**. Denn unsere **subjektiven Paradigmen stehen objektive Prinzipien gegenüber** Werten wie Fairness, Ehrlichkeit und Integrität.
Diese Prinzipien werden von den meisten Menschen befürwortet und können daher als Naturgesetzen ähnelnde Wertmaßstäbe gesehen werden, die dauerhafte Gültigkeit besitzen.
An diesen universellen Prinzipien lässt sich alles menschliche Verhalten messen. Je mehr unser Verhalten im Einklang mit ihnen ist, desto effektiver können wir mit unser Umwelt interagieren.
Und da unser Verhalten auf unseren persönlichen Grundüberzeugungen basiert, kann man sagen:
##Am eigenen Charakter zu arbeiten, bedeutet, persönliche Paradigmen an universellen Prinzipien auszurichten.
#Wer dauerhaft sägen will, muss regelmäßig seine Säge schärfen.
Wer den ganzen Tag damit beschäftigt ist zu sägen, aber niemals Zeit findet, seine Säge zu schärfen, macht etwas grundlegend falsch.
Denn wer dauerhaft produktiv sein will, muss sich auch darum kümmern, seine wichtigste Ressource zu bewahren: die eigene Arbeitskraft.
Dazu ist **proaktives Handeln** nötig, und zwar in den unterschiedlichsten Bereichen:
Um die körperliche Gesundheit aufrechtzuerhalten, sollte man **regelmäßig Sport** treiben, sich **gesund ernähren** und sich **vor starkem Stress schützen**.
Um sich geistig fit zu halten, sollte man möglichst **viele gute Bücher lesen**, **selbst schreiben** (z.B. Briefe, Tagebuch) und **regelmäßig aktiv die eigene Zukunft planen** und über **langfristige Ziele** nachdenken.
Auch auf die **soziale/emotionale Gesundheit** sollte man achten, indem man möglichst **viele positive Interaktionen** führt und seine sozialen Bedürfnisse niemals vernachlässigt.
Daneben ist auch die **spirituelle Gesundheit** wichtig für dauerhafte Produktivität: Das kann bedeuten, zu beten oder zu **meditieren**, aber auch, sich regelmäßig mit den **eigenen Werten und Normen auseinander zu setzen** und sie **bewusst zu reflektieren**.
Wichtig bei alldem ist es, sich **bewusst die Zeit für Erholung und Regeneration zu nehmen**. Die meisten Menschen denken, sie hätten dafür keine Zeit, doch langfristig gesehen zahlt sich die investierte Zeit vielfach in Produktivität und Wohlbefinden aus.
Diese Denkweise lässt sich auf alle möglichen Bereiche ausweiten, in denen Produktivität eine Rolle spielt: Auch Unternehmen sollten nicht nur an die Produkte denken, die sie herstellen wollen, sondern auch das Wohl der Produzenten (also z.B. der Mitarbeiter) im Auge behalten.
##Wer dauerhaft sägen will, muss regelmäßig seine Säge schärfen.
#Jeder Mensch kann proaktiv sein und sein Schicksal selbst in die Hand nehmen.
Es ist ein **menschliches Grundbedürfnis, aktiv zu handeln** und **Einfluss auf die Umwelt zu nehmen**. Jedem wohnt das Bedürfnis inne, proaktiv zu sein.
Dadurch unterscheidet der Mensch sich vom Tier: Das Tier folgt lediglich festen Programmen, die ihm eingegeben sind. Auf einen externen Reiz folgt eine Reaktion. Der Mensch hingegen hat Einfluss auf seine „Programme“. **Zwischen Reiz und Reaktion liegt Reflektion**. Kraft der Fähigkeit, sich selbst und sein Handeln „von außen“ zu beobachten, entscheidet der Mensch, wie er auf externe Einflüsse reagiert.
Ein extremes Beispiel echter Proaktivität war Viktor Frankl, der selbst im Konzentrationslager in der Lage war, die Kontrolle über seine eigenen Empfindungen zu bewahren. Er beschloss schlicht, dass ihm seine Peiniger im Innersten seines Selbst nichts anhaben konnten.
*Viele Menschen sind in ihrem Leben jedoch nicht proaktiv, sondern reaktiv. Sie reagieren auf externe Umstände und sind in ihrem Verhalten und ihren Emotionen von ihrer Umwelt abhängig. Nur wenn das Wetter gut ist, ist auch ihre Laune gut.*
**Proaktive Menschen hingegen machen ihr eigenes Wetter**. Sie sind **getragen von inneren Werten** und **übernehmen die Verantwortung für ihr eigenes Leben**. Ihr Verhalten ist bestimmt durch **persönliche Entscheidungen**, nicht durch äußere Bedingungen.
*Das zeigt sich auch im Sprachgebrauch: Reaktive Menschen machen äußere Umstände für ihr Schicksal verantwortlich. Sie sagen „Es war nicht mein Fehler“ oder „Es lag nicht in meinem Einfluss.“*
Proaktive Menschen nehmen ihr Schicksal selbst in die Hand: Was sie heute sind, sind sie aufgrund der Entscheidungen, die sie gestern getroffen haben. Sie sagen „**Ich entscheide mich für...**“ oder „Lass uns nach Lösungen für dieses Problem suchen.“
##Jeder Mensch kann proaktiv sein und sein Schicksal selbst in die Hand nehmen.
#Wer wirklich Bedeutungsvolles erreichen will, der braucht langfristige Ziele und ein Leitbild.
Viele Menschen arbeiten für „leere Erfolge“. Sie sorgen sich lediglich darum, effizient zu arbeiten, ohne jedoch effektiv zu sein.
*Effizient zu sein, also möglichst viel in möglichst kurzer Zeit zu schaffen, ist nutzlos, wenn man nicht weiß, wofür man es tut.* Wer nicht weiß, was wirklich wichtig ist und was er eigentlich erreichen will, der arbeitet, als würde er eine Leiter hinaufsteigen, die aber an der falschen Wand lehnt.
Um das zu vermeiden, ist es wichtig, sich **Klarheit über seine längerfristigen Ziele** zu verschaffen. Dazu kann es sinnvoll sein, sich die Beerdigungs-Frage zu stellen:
Was sollen die Menschen auf meiner Beerdigung über mich sagen?
An was für einen Menschen sollen sie sich erinnern?
Mit welchen Leistungen möchte ich im Gedächtnis der Menschen bleiben?
Wer sich seine **großen, langfristigen Ziele** klarmacht, kann alles, was er tut, an ihnen ausrichten.
Dafür kann es z.B. nützlich sein, ein **persönliches Leitbild zu formulieren und schriftlich festzuhalten**. In diesem Leitbild hält man sein persönliches Credo fest: die **grundlegenden Werte und Prinzipien**, an die man glaubt, und die **großen Ziele**, die man in seinem Leben erreichen möchte.
Das Leitbild fungiert als **unveränderliche Konstitution**, als **festgeschriebener Standard**, an dem alles andere gemessen und bewertet wird. Ein solcher Kompass verschafft dem Menschen Orientierung und Sicherheit.
##Wer wirklich Bedeutungsvolles erreichen will, der braucht langfristige Ziele und ein Leitbild.
#Um seine Ziele zu erreichen, sollte man das Ergebnis jeder Handlung möglichst bildlich vorwegnehmen.
Alle **Handlungen werden** eigentlich **zweimal vollzogen**: zunächst als **mentales Bild**, das das Ziel der Handlung vorwegnimmt, und erst dann in dessen **eigentlicher Ausführung**.
Je **genauer und passender bereits das mentale Bild** ist, desto **besser auch die Ausführung** der eigentlichen Handlung und **schlussendlich deren Ergebnisse**.
Daher ist es wichtig, sich immer zweier Dinge bewusst zu sein.
Erstens sollte man sich seine **langfristigen Ziele, seine Werte und Normen vor Augen halten**, an denen alle Handlungen ausgerichtet werden können. Man sollte immer genau wissen, auf welche Scheibe man eigentlich mit seinem Bogen zielen möchte.
Denn wer keine klaren Vorstellungen davon hat, was er erreichen möchte, ist lediglich passiver Spielball der Ziele anderer.
Zweitens sollte **für jede Handlung ein möglichst konkretes visuelles Bild entwickelt** werden, das vorwegnimmt, was genau erreicht werden soll. Man sollte sich also **bildlich vorstellen**, wie man mit dem Bogen ansetzt und ins Schwarze trifft.
Diese bildliche Vorwegnahme funktioniert in allen möglichen Kontexten. Die meisten erfolgreichen Leistungssportler sind beispielsweise gut darin geübt, sich genau zu verbildlichen, wie sie aus dem Startblock gehen, einen perfekten Lauf hinlegen und als erster das Ziel erreichen.
Aber auch in einem Unternehmen gilt das gleiche Prinzip: Zuerst muss eine möglichst bildliche Vision entwickelt werden, ehe diese durch konkrete Handlungen umgesetzt werden kann.
Und wie das Sprichwort sagt „Lieber zweimal fragen als einmal irregehen“ , ist es meist sehr sinnvoll, der geistigen Vorwegnahme und der Verbildlichung eines Ziels genügend Raum zu geben und sich nicht vorschnell in dessen Umsetzung zu stürzen.
##Um seine Ziele zu erreichen, sollte man das Ergebnis jeder Handlung möglichst bildlich vorwegnehmen.
#Wer effektiv sein will, der sollte immer unter der Maßgabe „Wichtiges zuerst“ handeln.
Wer proaktiv seine Umwelt gestalten will und ein klares Ziel vor Augen hat, braucht gute Gewohnheiten, die ihm dabei helfen, seine Ziele in Handlungen zu überführen.
Eine Mission oder Vision kann nur dann Wirklichkeit werden, wenn sie auch im Alltag gelebt wird.
Dazu ist kein komplexes Zeitmanagement nötig. Die meisten Zeitmanagement-Techniken führen nur zu einer gesteigerten Effizienz, ohne dagegen jedoch die Effektivität der Arbeit zu verbessern. Außerdem belasten sie oft zwischenmenschliche Beziehungen und sind daher langfristig kontraproduktiv.
Es genügt meist, den einfachen Grundsatz zu verinnerlichen: „**Wichtiges zuerst**“.
„Wichtiges zuerst“ bedeutet **rigoroses Priorisieren**: Wichtiges wird erledigt, Unwichtiges bleibt liegen, wird delegiert und vertagt.
Woran erkennt man aber, was wichtig ist? Wichtig sind die Dinge, die uns unseren großen Zielen näher bringen und die im Einklang mit unserem persönlichen Leitbild, unseren Werten und Normen sind.
Dabei handelt es sich meist nicht um die sehr dringlichen Dinge, die vielen kleinen Aufgaben, die im Alltag anfallen. Meist handelt es sich um Projekte und Aufgaben, die keine zeitliche Dringlichkeit besitzen, die aber mit unseren großen Visionen zu tun haben und langfristig viel bewirken können.
Um sich diesen wichtigen Aufgaben widmen zu können, ist es **wichtig, Ja und Nein sagen zu lernen**. Wenn in uns ein großes Ja für unsere Ziele brennt, dann sollten wir auch in der Lage sein, Nein zu sagen, wenn wir gebeten werden, etwas zu tun, das uns nicht unseren Zielen näher bringt.
##Wer effektiv sein will, der sollte immer unter der Maßgabe „Wichtiges zuerst“ handeln.
#Wer „Win/Win” denkt, bekommt sein Stück vom Kuchen und gleichzeitig langfristige Beziehungen zu anderen.
Die meisten Menschen sind von einem tief verwurzelten *Win/Lose-Paradigma* geprägt. Sie sehen jede Situation im Leben als *Wettkampf* und treten zu anderen in Wettbewerb, um *sich das größte Stück vom Kuchen zu sichern*.
Die meisten Situationen des Lebens machen jedoch überhaupt keinen Wettbewerb erforderlich. Meistens gibt es genug Kuchen für alle, und es ist am besten, wenn alle Beteiligten eine **Win/Win-Lösung anstreben**.
Denn ein großer Nachteil der Win/Lose-Mentalität besteht darin, dass, wenn zwei Win/Lose-Menschen aufeinander treffen, das Ergebnis der Interaktion meist Lose/Lose ist. Beide verlieren, und der Hund frisst den Kuchen, der im Streit zu Boden gefallen ist.
Außerdem entwickelt sich zwischen zwei Menschen, die immer im Wettbewerb zueinander stehen, *keine langfristige positive Beziehung*. Eine solche Beziehung zu vielen Menschen aufbauen zu können, ist einer der wesentlichen Vorteile des Win/Win-Denkens.
Denn positive zwischenmenschliche Beziehungen sind ein wertvolles Gut und die Grundlage wahrer Effektivität.
**Win/Win ist eine Geisteshaltung**, in der stets die Lösung gesucht wird, die **für alle Beteiligten wünschenswert** ist. Sie erfordert ein **Umdenken** von „Ich muss mir mein Stück vom Kuchen sichern“ hin zu einem „**Es ist genug für alle da**“.
Das bedeutet, immer solange zu verhandeln und zu kommunizieren, bis eine Lösung gefunden ist, die alle Seiten gut finden. Das ist nicht leicht und **erfordert sowohl Einfühlungsvermögen wie auch Geduld**.
Im Resultat ergeben sich jedoch **langfristige Beziehungen und ein gegenseitiges Vertrauen**, von denen alle Seiten profitieren.
##Wer „Win/Win” denkt, bekommt sein Stück vom Kuchen und gleichzeitig langfristige Beziehungen zu anderen.
#Um stabile Beziehungen zu anderen zu führen, müssen emotionale Bankkonten gepflegt werden.
**Jede zwischenmenschliche Beziehung verfügt über eine Art emotionales Bankkonto**, das widerspiegelt, wie viel beide Personen bereits in die Beziehung investiert haben.
Je größer der Kontostand, desto größer das Vertrauen.
Daher ist es wichtig, konstant auf das Konto einzuzahlen und nur möglichst selten eine Abhebung zu machen.
Eine **Einzahlung** ist es beispielsweise, eine **Win/Win-Lösung** zu finden, ein Versprechen einzuhalten oder dem anderen aufmerksam zuzuhören.
Eine Abhebung hingegen wäre es, eine Win/Lose-Lösung zu finden, ein Versprechen zu brechen oder dem anderen nur halbherzig zuzuhören.
Wer einen möglichst hohen Kontostand erreichen möchte, muss die Bedürfnisse und die Mission des anderen verstehen und sich in ihn hineinversetzen.
In den täglichen Interaktionen geht es vor allem darum, **Zusagen einzuhalten**, auch bei Kleinigkeiten **höflich und einfühlsam zu bleiben** und vor allem **loyal** zu sein.
Wenn einmal eine Abhebung vom emotionalen Bankkonto stattgefunden hat, sollte man sich für diese **ehrlich entschuldigen**. **Menschen verzeihen gerne einem reuigen Sünder**. Daher lohnt es sich, die **Größe aufzubringen**, das **eigene Versagen einzugestehen**.
##Um stabile Beziehungen zu anderen zu führen, müssen emotionale Bankkonten gepflegt werden.
Wer Einfluss auf andere nehmen will, sollte lernen, ein **empathischer Zuhörer** zu werden.
* Wie sehr vertrauen wir einem Arzt, der in kürzester Zeit zu einer Diagnose kommt, ohne uns wirklich zugehört zu haben?
* Wie hilfreich ist ein Optiker, der uns seine eigene Brille gibt, mit dem Hinweis, er selbst sehe damit perfekt, also müsse sie auch bei uns funktionieren?
Auch wenn die meisten von uns den Kopf schütteln, wenn sie von solchem Verhalten hören, benehmen wir uns im Alltag doch oft ähnlich, und das insbesondere in Gesprächen. Wir hören nicht richtig zu und wissen schnell, was wir erwidern wollen. *Wir schließen von uns selbst auf andere* und suchen nach schnellen Lösungen, die wir dem anderen „verschreiben“.
Solcher Rat wird jedoch in der Regel nicht angenommen, denn nur wer sich mit seiner speziellen Situationen verstanden fühlt, traut dem Urteil eines anderen.
Um effektiv mit anderen umgehen zu können und als Zuhörer und Ratgeber ernst genommen zu werden, ist es daher wichtig, sich die **Fähigkeit des empathischen Zuhörens** anzueignen.
Sie erfordert zunächst einen **Paradigmenwechsel**: weg von „Ich höre zu, um zu antworten“, hin zu „**Ich höre zu, um mein Gegenüber wirklich zu verstehen**“.
Empathisches Zuhören bedeutet, dem anderen **aktiv zuzuhören**, das **Gesagte in eigenen Worten wiederzugeben**, die Gefühle des anderen zu spiegeln und ihm insgesamt dabei zu helfen, seine eigenen Gedanken zu strukturieren.
Es zu erlernen, erfordert zu Beginn viel Zeit, die zu investieren sich später aber vielfach auszahlt.
Denn wer empathisch zuhört, wird merken, dass viele Menschen sich gerne öffnen und auch zugänglich für Ratschläge und Meinungen sind sofern sie es mit einem guten, verständnisvollen Zuhörer zu tun haben.
##Wer Einfluss auf andere nehmen will, sollte lernen, ein empathischer Zuhörer zu werden.
#Synergien entstehen, wenn Gruppenmitglieder einander mit Offenheit und Respekt begegnen.
Synergien sind überall in der Natur zu finden. Durch die Interaktion einzelner Teile entsteht eine Summe, die größer ist als die einzelnen Beiträge.
Wer wirklich effektiv sein will, kann dieses Prinzip auf sein Leben und seine Arbeit übertragen.
Synergie in Interaktionen mit anderen Menschen bedeutet, **Unterschiede wertzuschätzen** und offen zu sein. Jeder Mensch sieht die Welt aus einer anderen Perspektive. Jeder bringt bestimmte Stärken mit. Und durch die **Nutzung gemeinsamer Ressourcen** gelingt es, **individuelle Schwächen zu kompensieren**.
In der Umsetzung bedeutet dies, das eigene Bedürfnis nach Sicherheit und Struktur zu überwinden und die **Interaktion mit anderen als ein Abenteuer zu sehen**, dessen Ergebnis völlig offen ist und dem man mit größtmöglicher Aufgeschlossenheit begegnet.
Vom Einzelnen verlangt dies ein hohes Maß an Selbstsicherheit und den festen Glauben daran, dass in der Interaktion **aus den Beiträgen aller Beteiligten etwas Größeres, Besseres entstehen** kann.
Wenn **synergetisch gearbeitet** wird, **hören Menschen einander zu**, **versetzen sich in die Perspektive ihres Gegenübers** und **bauen auf den Beiträgen der anderen auf**.
Diese Kultur von Kooperation und Vertrauen entsteht nur in Gruppen **sehr reifer Individuen**, die **einander mit Respekt begegnen** und in **zwischenmenschliche Beziehungen zueinander investieren**.
Die Resultate sind nicht vorhersehbar, und oftmals bewegt sich synergetische Arbeit an der Grenze zum Chaos. Davon sollte man sich nicht entmutigen lassen, sondern fest darauf vertrauen, dass am Ende ein Ergebnis erzielt wird, das die Summe der Beiträge übersteigt.
##Synergien entstehen, wenn Gruppenmitglieder einander mit Offenheit und Respekt begegnen.
@@ -0,0 +1,65 @@
---
layout: post
title: "Rechte und Pflichten eines Reiseveranstalters"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Hallo liebe Abenteurer! Wie ihr unserem letzten Artikel entnehmen konntet, haben wir uns vorgenommen, Shareventure auf rechtssichere Beine zu stellen. Damit wir euch schon bald die nächste aufregende Tour anbieten können, verfolgen wir dieses Thema mit voller Kraft! # Was ist ein Reiseveranstalter Der Begriff Reiseveranstalters ist zunächst einmal juristischer Natur. Man erfüllt ihn, wenn man eine Pauschalreise im Sinne des BGB (§ 651 a) anbietet. Das bedeutet: zwei Hauptleistungen werden zu einem Gesamtpaket unter eigenem Namen geschnürt. Typische Beispiele sind dafür: Beförderung und Unterkunft, Beförderung und Verkaufsveranstaltung (Werbefahrt, Kaffeefahrt etc.), Unterkunft und Hobbykurs/Sport oder die Kreuzfahrt. Erfüllt man den Tatbestand gilt man als Reiseveranstalter und muss damit bestimmte Pflichten erfüllen, solange man nicht von den Ausnahmeregelungen (auf diese gehen wir hier nicht weiter ein) betroffen ist.
<!-- more -->
## Welche Pflichten hat man
Die wichtigsten Pflichten sind zunächst einmal, dass man als Reiseveranstalter natürlich ein angemeldetes Gewerbe benötigt. Dazu kommen bestimmte Versicherungen, die die Kunden des Reiseveranstalters mit absichern. Haftungsrisiken
## Die Gewerbeanmeldung Leipzig Kosten Notwendige Unterlagen
## Pflichtversicherungen für Reiseveranstalter
Als Reiseveranstalter ist man verpflichtet bestimmte Versicherungen abzuschließen. In einem vorherigen Beitrag haben wir schon abgedeckt, was für Rechten und Pflichten man generell hat. Die Versicherungen sind eine konkrete Ausprägung dieser Pflichten.
Vorne weg: wir sind keine Profis der Versicherungsbranche. Wir wollen aber unsere Erfahrungen mit euch teilen, falls euch das Thema auch betreffen sollte oder ihr über Google auf unserer Seite gelandet seid und euch zu dem Thema “Wie werde ich Reiseveranstalter” schlau machen wollt.
Zudem sind wir große Freunde von Transparenz und klarer Kommunikation. Unsere Abenteurer sollen wissen, was hinter der Bühne abläuft! Deshalb jetzt rein ins Getümmel!
Als Reiseveranstalter muss man sich über folgende Versicherungen Gedanken machen:
1. **Insolvenz-Versicherung**: Schützt die Reiseteilnehmer vor Zahlungsunfähigkeit unseres Unternehmens.
2. **Reiseveranstalter-Haftpflichtversicherung**: Schützt das Unternehmen gegen Ansprüche der Reiseteilnehmer aus Personenschäden, Sachschäden und Vermögensschäden
3. **Berufshaftpflichtversicherung**: Schützt uns als Reiseleiter vor Ansprüchen der Reiseteilnehmer.
Die Insolvenzversicherung ist das A und O. Hier regiert der Kapitalismus. Wenn wir nicht mehr zahlen können und deshalb leider eure Abenteuerreise ins Wasser fällt, sollt ihr zumindest euer Geld zurück bekommen. Das hat der Gesetzgeber mit dieser verpflichtenden Versicherung richtigerweise sichergestellt. Immer wenn ihr eine Reise bucht, bekommt ihr von uns einen Insolvenzversicherungsschein. Er gibt euch einen direkten Anspruch gegenüber der Versicherung. Ihr könnt euch also sicher sein, dass ihr entweder an unseren Abenteuern teilnehmt — oder im schlimmsten Fall euer Geld wieder bekommt!
Mit der Reiseveranstalter-Haftplichtversicherung kommen wir in den Bereich der Schäden. Sollte auf unseren Reisen etwas schlimmes passieren, wofür wir als Gesellschaft verantwortlich sind, dann kümmert sie sich und begleicht mögliche entstandene Schäden. Die Versicherung zahlt, wenn etwas passiert, was wir zu verschulden haben. Dabei ist allerdings wichtig zu verstehen, dass diese Versicherung deutlich enger gefasst ist, als es zunächst klingt.
Wir geben unser Bestes, um euch gut auf eure Abenteuer-Reise vorzubereiten. Eure Sicherheit ist unser höchstes Gut. Solltet ihr euch aber entgegen unserer Anweisungen verhalten, verliert ihr auch eure Versicherungsansprüche! Deshalb ist es ungemein wichtig, dass ihr euch an die Anweisungen unseres Teams haltet! Nur so ist gewährleistet, dass ihr im schlimmsten Fall auch abgesichert seid!
Zudem ist es für manche Touren sinnvoll, bestimmte Individualversicherungen abzuschließen, um auf Nummer sicher zu gehen. Wenn ihr das Bedürfnis dazu habt, sprecht uns an. Wir stehen in engem Kontakt mit Versicherern, die euch beratend zur Seite stehen können.
Die dritte im Bunde ist ein Sonderfall, denn hier kommen mehrere Dinge zusammen. Zunächst ist Shareventure an einer Stelle ein Sonderfall: wir bieten euch nicht hauptsächlich Abenteuer an, die wir von anderen einkaufen, sondern mischen selbst mit! Das heißt wir müssen uns darum kümmern, dass unsere Abenteurer abgesichert sind, wenn wir persönlich als Reiseleiter mal einen Fehler machen.
Wir finden, der Gesetzgeber hat hier ganz gut mitgedacht und die wichtigsten Aspekte berücksichtigt. Das schöne ist: ihr müsst euch um so gut wie nicht kümmern, als um eure Abenteuervorbereitung und könnt trotzdem mit ruhigem Gewissen mitkommen. Denn um die wichtigsten Versicherungsthemen haben wir uns schon gekümmert!
## Private Touren und deren Risiken
Bisher sind alle Touren im privaten Rahmen veranstaltet worden. Aber gibt es so etwas überhaupt? Durch Zufall sind wir neulich darauf aufmerksam gemacht worden, dass sich viele private Veranstalter in einer gesetzlichen Grauzone bewegen. Denn es gibt gewisse Regelungen, die dazu führen, dass man vor dem Gesetz als Reiseveranstalter gilt, was gravierende Konsequenzen nach sich zieht!
Als Reiseveranstalter zu gelten bedeutet, dass man für die Reisedurchführung ein angemeldetes Gewerbe benötigt und verpflichtet ist die gesetzlich vorgeschriebenen Versicherung abgeschlossen zu haben. Da wird aus der ursprünglich einfach gedachten Wandertour mit Freunden plötzlich ein rechtliches "Monster". Und ja, das gilt auch, wenn das ganze privat abläuft! Denn laut Gesetz gilt man als Reiseveranstalter, wenn man zwei oder mehr Hauptleistungen einer Reise zu einem Pauschalpreis zusammenfasst.
Eine Hauptleistung ist zB die Verpflegung, die Unterbringung, die Anreise, usw. Natürlich gibt es Ausnahmen: wenn man diese Reisen nicht öfter als zwei Mal im Jahr durchführt und die Reisen dabei eine bestimmte Stundenzahl nicht überschreiten. Aber man merkt doch recht schnell, dass diese Ausnahmen eher knapp bemessen sind.
Im Normalfall ist das natürlich unerheblich, da nichts passiert. Und da die Freunde auch keine Ansprüche geltend machen: wo kein Kläger da kein Richter. Aber was passiert, wenn der Freund eines Freundes dabei ist? Man kann sich zügig und ohne große Probleme Szenarios ausdenken, wo man als Organisator doof da steht (oder besser stehen könnte).
Auch unsere bisherigen Touren standen unter diesem Gesichtspunkt auf wackeligen Beinen. Wir sind froh, dass unsere bisherigen Reise einwandfrei abgelaufen sind und alle Teilnehmer zufrieden waren -- und vor allem: das nichts passiert ist!
Denn im Zweifelsfall ist nicht einmal der Organisator der Blöde, sondern der Betroffene. Und für uns ist Sicherheit und Vertrauen das A und O! Wir wollen auf jeden Fall, dass alle unsere Abenteurer sich sicher sein können, ein gutes Erlebnis zu haben und im Notfall abgesichert zu sein!
Deshalb haben wir uns vorgenommen, dass bei den zukünftigen Reisen alles mit Recht und Ordnung zugehen soll. Das bedeutet für unsere potentiellen Abenteurer, dass sie sich in Zukunft auch rechtlich auf uns verlassen können! Die notwendigen Versicherungen sind garantiert!
Des Weiteren stehen wir euch beratend zur Seite, wenn ihr euch für euer Abenteuer vorbereitet. Denn der individuelle Versicherungsschutz ist trotzdem ein Thema für euch! Bei Fragen, schreibt uns einfach!
Euer Shareventure Team
@@ -0,0 +1,69 @@
---
layout: post
title: "Anleitung für kleine Start-ups"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
<!-- more -->
## Todo
- Angebotserstellung: Invoice Plane
- E-Mail-Template
- Email mit IP verbinden damit alles von einer Adresse kommt
- PDF-Template
- Anschreiben-Text
- Rechnungsstellung: Invoice Plane
- Steuern: Elsteronline
- Todo-Liste: 2Do, Trello
- Konto
- Gewerbeanmeldung
- Steuerliche Erfassung
- Steuernummer
- kleinunternehmerregelung
- ggf Gesellschaftervertrag
- Social:
- Facebook (Page, Profile Picture, Cover picture)
- Email (adresse, signature)
- Sensible Data management (keepassx?)
-
## Selbstständig in Leipzig.
### Gewerbe-Anmeldung
Der erste Schritt in die Selbstständigkeit ist in der Regel die Anmeldung eines Gewerbes. In Leipzig ist das Gewerbeamt im **technischen Rathaus** (**Adresse**). Man wartet dort meiner Erfahrung nach etwa 30-45 Minuten.
Die eigentliche Anmeldung dauert etwa 15 Minuten. Die Anmeldung des Gewerbes kostet in Leipzig um die 35 EUR.
Um Zeit zu sparen, kann man sich im Vorhinein über den Gegenstand des Gewerbes klar werden und diesen Text vorbereiten.
Mein eingetragener Gewerbe-Gegenstand ist bspw *Unternehmensberatung, Web-Design und Web-Entwicklung*.
### Steuererklärung
Zwei, drei Wochen später kommt dann Post vom Finanzamt, das einen Fragebogen zur Erfassung zuschickt. Dort kann auch die Steuermummer und USt-ID (soweit gewünscht) beantragt werden.
Für Unternehmer, die gerne die Umsatzsteuer ausweisen möchten -- und damit zum Vorsteuer-Abzug berechtigt werden --
Einnahmen-Überschuss-Rechnung
### Kunden finden
### Bestandteile einer Rechnung
- Rechnungssteller (vollständiger Name und Anschrift)
- Rechnungsempfänger (“)
- Steuernummer des RgStellers
- Datum
- Rechnungsnummer (eindeutig)
- Menge & Artikelbezeichnung bzw. Umfang der Leistung
- Datum der Lieferung (auch wenn identisch mit oben!)
- Netto-Betrag
- Steuersatz
- Steuerbetrag
@@ -0,0 +1,32 @@
---
layout: post
title: "Akrasia"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
## Akrasia
Begriff aus dem Griechischen: Handeln entgegen besserem Wissen.
<!-- more -->
## Gründe für Akrasia
Time inconsistency: Sofortige Gratifikation wird höher gewichtet, als langfristige. Langfristige Pläne sind für das zukünftige Selbst, aber wenn man dann in der Situation ist, dann geht es plötzlich um das tatsächliche Selbst.
## Strategien zur Begegnung von Akrasia
### Design future actions
Wo möglich: Automatisierung der schlechten Angewohnheiten. Löschen der Versuchungsobjekte (z.B. Deinstallieren von Dota).
### Reduce friction of starting
Die Arbeit selbst ist nicht schwer. Der Start ist schwer. Es ist wichtiger anzufangen, als erfolgreich zu sein. Wer anfängt, geht vorwärts. Ergebnisse sind erst dann wichtig, wenn man kontinuierlich anfängt.
### Utilize implementation intentions
Konrekte Aufgaben definieren: "Am [Date] trainiere ich im [ORT] für [ZEIT].
## Enkrateia, der Gegenentwurf
Being in charge. In power over oneself.
## Compound habitrest
Kleine Gewohnheiten finden und daran halten. Gewohnheiten zerlegen. Wie Projekte. Wenn es failed, get back on track. Fast. Never miss a habit twice.
@@ -0,0 +1,63 @@
---
layout: post
title: "Enchiridion Reduced"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
1) Some things are in our control and other things are not.
2) Shun only those things you have the power to avoid; desire only those things you have the power to acquire.
3) Look first at things as they are, letting your own sentiments about them fall to the wayside.
4) Practice negative visualization and keep your will in alignment with nature.
5) It is our perceptions of things, rather than the things themselves, that cause us disturbance, so choose your perceptions wisely.
6) Be proud only of what is under your control: the choices you make.
7) Remember that your purpose is to steer a virtuous course through life, and that the things which come and go are merely incidental of that purpose.
8) Will things to happen as they will.
9) Nothing can alter the power of our own will.
10) Whenever you are confronted by a problem ask of yourself what skills or knowledge you possess to help overcome it.
11) The loss of something is merely a return to before you had it.
12) Do not allow external indifferents to determine your state of mind; that is the job of your will.
13) It is no good being indifferent to externals if you are not also indifferent to the opinions of others.
14) Freedom is desire without expectation.
15) Practice moderation and, failing that, abstinence.
16) Do not judge those who do not understand that it is only their choices that cause suffering, but rather offer them a shoulder to cry on.
17) Whichever part you are given in life, play it well!
18) Omens are a fool's game.
19) Symbols of status say nothing of their owner's attitude towards external indifferents. In this capacity we are all equal.
20) If someone strikes you it remains within your power to either take offence or not.
21) Remember always that bad things and death will happen to you, and your thoughts will remain true and free of vice.
22) If learning Stoicism creates in you a supercilious sentiment towards others then you have not yet learnt Stoicism.
23) The only validation you need is from yourself.
24) True friends help one another to acquire virtue rather than external indifferents.
25) If someone has something you don't, rejoice for them and be glad you have not had to pay the price for it.
26) We should respond to the breaking of our favourite cup just as if it had been our neighbour who broke their cup; this same principle also applies to the loss of our loved ones.
27) The only bad is the absence of virtue in your own actions.
28) It is your choice whether or not to take offence to an insult; but doing so ingratiates the insulter.
29) Do not set a goal without first considering what its achievement requires and what might result from it in the worst case as well as the best.
30) Focus not on how others treat you but on how you must treat them in order to keep your will in accordance with nature.
31) There is no need to praise or curse the gods for the state of externals; only trust that they rule with wisdom.
32) Divination of Triumph and Disaster should be met without Desire or Aversion.
33) Be authentic; speak only when necessary; practice abstinence; avoid making promises; don't be promiscuous; keep your faults salient; be wary of the corrupting influence of others; aim for sagitude.
34) When faced with temptation consider first how you will regard yourself after either gratification or abstention.
35) Do the right thing regardless of the opinions of others.
36) Courtesy and greed are mutually exclusive.
37) Don't take on a role you know you can't play.
38) Just as you choose your steps to avoid rusty nails, choose your thoughts to avoid stress.
39) You can satisfy your needs but if you try to acquire more than that your desires will only grow.
40) Women are also people.
41) Food, exercise and sex should be done incidentally with the vast majority of our strength directed towards reason.
42) A perpetrator of injustice against you has deceived themselves in the face of nature and, in doing so, have harmed themselves more than they have harmed you.
43) All things have two handles.
44) You are not your possessions, nor are you your skills.
45) Avoid moralising about the behaviour of others but rather describe what they are actually doing.
46) Don't say what should be done; do what should be done.
47) Privation for the sake of praise is not privation.
48) Keep watch over your will.
49) Intellectualism for its own sake is blind to nature.
50) Do not stop taking steps towards your own ideals.
51) Live virtuously and stand aside for Fate.
@@ -0,0 +1,25 @@
---
layout: post
title: "How to Change Your Life"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
I was always annoyed by people, who were complaining, but not doing or changing anything about their problems. Complaining about their families, about their jobs - about their life. Everyone knows at least one person like that. I always thought that if they were not happy, they should change something! But since I am a very polite person, I didnt get in their faces. It would not have mattered anyway, I guess.
And now my life has developed in a way, that I am not happy anymore. And I dont want to be on the "complaining and not doing anything about it" end. I want to tackle the situation head on. I want to work on my life.
But it is not as easy as you might think. To change your life for the better, it is required to identify what to change, what to change it into and how to change it in the first place. It is necessary to identify what really matters to you personally. Summarised: You need to figure out a plan, that makes you happy in the long run.
And creating this plan can be really intimidating. It requires you to be brutally honest with yourself. Because it might be necessary to change parts of your life, that - at the moment - seem integral to it. It might be necessary to sever ties to people, who are currently very present in your life. It might be necessary to change your deeply entrenched behaviours.
To create this plan, there lies a lot of work ahead of you. It is a time consuming process. Nobody but you can start it. If you are unhappy, the sooner you sit down and work on it, the sooner you can start moving in the right direction.
I decided to start this process. Since plans are basically a list of goals and following a plan means to keep track of your success in reaching these goals, you will need something to write these goals down and track them. A computer with project or goal management software, an excel sheet, word, or a classic notebook. The choice is yours and you should use the tool you are the most comfortable with.
I will be using a very nice classical notebook. I consider this notebook my treasure which holds all the steps to happiness.
@@ -0,0 +1,22 @@
---
layout: post
title: "LineageOS on Xiaomi Redmi 4X and Note 5"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
1. Unlock Bootloader: http://en.miui.com/unlock/
1. Apply
2. Wait
3. Unlock with MiFlash Unlock
2. Flash Custom Recovery: TWRP Recovery via ADB
3. Install LineageOS via TWRP
4. Install MagiskManager from Github
5. Install Magisk via MagiskManager
6. Install XposedInstaller (find file in MagiskModule Readme)
7. Install Xposed as MagiskModule
8. Install GravityBox via Xposed
@@ -0,0 +1,25 @@
---
layout: post
title: "The Hamburger"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Sentence 1: State the problem
Sentence 2: State the consequences of the problem
Sentence 3: State your solution
Sentence 4: State the consequences of the solution
Most hamburgers are larger than what can be held with one hand. This makes them hard to eat. We present a new type of hamburger, called the Hand Burger, that is small enough to hold in one hand. Experimental results show that the Hand Burger increases eating speed by up to 150%.
The node_modules directory of Node JS applications often contain multiple copies of the exact same file. This increases the size of the node_modules directory and decreases application startup speed. We have developed a caching scheme for Node JS modules that maintains a single copy of each unique file. This mechanism reduces the size of the node_modules directory by 75% for the most commonly used Node JS applications and increases startup speed by 25% on average.
Horse-drawn carriages have a hard time moving on land because of vegetation. This makes travel slow, or outright impossible. We present a novel concept that we call roads. Our measurements show that roads decrease travel time from years to days to reach the 20 most popular destinations throughout the Roman Empire.
@@ -0,0 +1,75 @@
---
layout: post
title: "Die Grundstruktur eines Corporate-Design-Handbuchs"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
- Titelseite
- Impressum
- Lizenz
- Kontakt
- Konzeption und Gestaltung
- CD Guidelines, inkl. Grund für CD: `In diesem Manual werden für alle, die gra sche Gestaltungsleistungen für X erbringen, verbindliche Leitlinien für Corporate Medien de niert. In der Regel sind diese so formuliert, dass dem Anwender hinreichend große Gestaltungs- freiheit in einem möglichst exakt de nierten Gestaltungsrahmen eingeräumt wird. Als Teil der Imagebildung hat das Corporate Design erhebliche Bedeutung. Es vermittelt visuell, wofür die Unternehmensphilosophie von Xsteht.`
- Inhaltsverzeichnis
- Logo:
- Logovarianten (einfarbig, zweifarbig, s/w, negativ)
- Schutzzone
- Logogrößen (Din A1-A7)
- Logo-Anwendungsbeispiele (falsch, richtig)
- Farben:
- Primärfarben
- Sekundärfarben
- Typografie:
- Font Vorstellung
- Liste erlaubter Fonts
- Bildwelten: Typische Bilder, die in Publikationen verwendet werden dürfen
- Anwendungsbeispiele
- Internet
- Briefpapier
- Visitenkarten
- Powerpoint
- Anzeige Porträt
- Anzeige Landscape
- Broschüre (Vorder-/Rückseite, Inhalte)
- Newsletter
- T-Shirts, Kugelschreiber, Keychains, usw.
# Corporate Design
In jedem Bereich: Anwendungsbeispiele
Vorwort (Tipps und Tricks wo man lizenzfreie Fotos und Icons usw her bekommt)
1. Basiselemente
1.1 Logo (Logovarianten, Negative, Schutzzone, Größen)
1.2 Farben (Farbpalette festlegen, Affinity/PS-Farbpalette zur Verfügung stellen)1.3 Typographie (Source Sans Pro)
1.4 Grundraster
2. Gestaltungselemente
2.1 Raster
2.3 Auszeichnungselemente (Infobox, Störer)
2.4 Illustrationen (CD-konforme Bilder neutral zur Wiederverwendung)2.5 Diagramme
3. Geschäftsausstattung
3.1 Briefbogen und Visitenkarte
3.2 Weitere Materialien
3.3 Adressblock
4. Publikationen
4.1 Broschüren DIN A4
4.2 Broschüren DIN A6
4.3 Broschüren Titel
4.4 Einladungskarten
4.4 Flyer DIN A6
4.5 Postkarten DIN A6
4.6 Plakate DIN A1 und A0
5. Bildschirmdesign
5.1 Weblayout
5.2 Microsites
5.3 Powerpoint
5.4 Sharepics
6. Sonstiges
6.1 Word-Vorlagen (Office)
6.2 Messewände und Roll-ups
6.3 Merchandising und assoziierte Logos (T-Shirts, Kugelschreiber, Flagge)
@@ -0,0 +1,68 @@
---
layout: post
title: "How to Bargain"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
**Note, the method detailed in this post works best for single-issue negotiations. If you're going through a messy divorce, let's say, and you're trying to negotiate every single aspect of your life, then things get a little more complicated. You can still use the strategies listed below, but they work best when you're trying to achieve ONE goal -- like lowering your cable bill or getting more vacation days at work.**
Most people (myself included) are hesitant to negotiate, *especially* when it comes to sensitive issues like our salaries or the price of a new home.
But there are two things worth knowing about negotiation...
* It's fucking uncomfortable, but it can be worth a LOT of money. If you start a new job and negotiate your salary $1,000 higher than the initial offer, you've set a new baseline for your earning. Over 10 years, if you did *nothing* but collect your 3% merit increase every year, that one conversation was worth $13,000+. And conversely, if you negotiate lower interest rates on your credit cards, a cheaper cable bill, a smaller car payment, etc., the savings start piling up quickly.
* You negotiate everything in pretty much the same way -- whether it's the $600,000 price tag of the house you want to buy, or where you and your spouse want to go for dinner. It all revolves about three parameters that you develop before entering a negotiation.
**Step #1: Figure out what you want.**
This is called your *aspiration point*. It can be anything you want, as long as it's specific and measurable. For example, if you wanted a salary increase, you wouldn't tell yourself, "I want more money." You'd say, "I want to earn $5,000 more annually." Your aspiration point needs to follow two rules:
* **Make it ambitious.** Don't sell yourself short. If you think you have a realistic chance of getting a $5,000 raise, then make your aspiration point $10,000.
* **Keep it realistic.** This seems like it violates the *make it ambitious* rule, but if your aspiration point is TOO crazy ("Boss, I demand a raise of *A MILLION DOLLARS A YEAR*"), you'll lose all credibility in the negotiation. Do a little research on whatever you're trying to negotiate, and make sure your aspiration point is ambitious, but not fucking absurd.
**Step #2: Figure out how little you're willing to accept.**
This is called your *reservation point,* and it's the absolute shittiest deal you'd be happy with. Using the salary example, let's say your reservation point is $1,000 a year. You asked for $10,000, you're hoping for $5,000, but shit, you'd take $1,000 if push came to shove.
If, after some back-and-forth discussion, your boss says, "Sorry kid, you're an awesome employee, but the best I can do for you is $1,500..." then you *take the motherfucking deal*. Any offer that falls between your aspiration point and your reservation point is called *winning the negotiation*. Congratulations.
So how do you know if you've set a good reservation point? Easy. There's only one rule:
* **It has to be better than your BATNA.** What's a BATNA? Great question. See Step #3.
**Step #3: Figure out what you're going to do if the negotiation doesn't work.**
This is your BATNA -- the **B**est **A**lternative **T**o **A** **N**egotiated **A**greement. And it's your source of power in every negotiation. Seriously, never *ever* enter a negotiation without a BATNA. You will lose.
If we stick with our salary increase scenario, your BATNA might be another job offer. "I just received an offer to work downtown, for $1,000 more a year, and if I can't reach an agreement with my current boss, I'm going to accept the offer." However, if you're looking to lower the price of your car insurance, your BATNA won't be so drastic: "I'm going to find another insurance company who will charge me less money."
It's just a Plan B. That's all. But a good BATNA needs to be three things:
* **Honest and realistic.** If you know, deep down in your heart, that you won't actually go through with your BATNA, then it's fucking useless. A BATNA is your Plan B. It needs to be a realistic option for you.
* **Worse than your reservation point.** If your BATNA is better than your reservation point, then your reservation point needs to go higher. After all, why would you walk away from your negotiation before you've reached your floor?
**Step #4: Use these parameters to guide your negotiation.**
Negotiation is about compromise. Steps #1, #2, and #3 help you establish what you *will* compromise over, and what you *won't* compromise over. Once you have those in place, you're going to bargain with the other party until you're offered a deal that's better than your reservation point. If that point never comes, then you exercise your BATNA and walk away from the table.
[Here's a visual.](http://i.imgur.com/VpA7dWx.png)
There are a few key points to keep in mind during the actual negotiation.
* **It's okay to share your aspiration point.** Feel free to tell the other party what you want. If they don't know what your goals are, then it makes it harder for them to compromise, right?
* **If the deal isn't going well, it's okay to share your BATNA.** Your BATNA shouldn't be flaunted over the other party, but it's fair to say, "Listen, I want this to work out for both of us, but I'm prepared to do X, Y, or Z if we can't reach an agreement."
* **Never, ever, ever, ever, ever, ever share your reservation point.** If they discover the worst deal you're willing to accept, then guess what? They're going to make you that offer. And guess what? You're going to accept it, because you've lost all leverage.
* **If you can guess the other party's reservation point, you win.** Correctly guessing the other party's reservation point is an automatic *I WIN* button in negotiation. Inexperienced negotiators might actually fucking *tell you* their reservation value: "Times are tough. All I can afford is $200." Is $200 higher than your reservation value? If it is, *negotiation over.*
* **If you're negotiating with someone you care about, your reputation is more important than getting an optimal deal.** If you're negotiating the price of lawn service with your best friend's brother, you might have the acumen required to absolutely fucking destroy him. Restrain yourself. Same goes for coworkers you'd like to work with again, or small businesses you value. Don't negotiate in a way that will compromise your reputation. Always be as fair as possible. Now, on the other hand, if you're negotiating with the random customer service rep at Comcast, go fucking crazy. Who cares?
* **If you realize you're not adequately prepared to negotiate, it's okay to reschedule and walk away.** Midway through the negotiation, you might realize that your reservation point is way too low. Or your BATNA has a major hole in it. Or your aspiration point is way higher than it should be. It's okay to say, "You know what? Based on some things I've learned from our discussion, I'd like to take another day or two to revise my thinking. Can we reschedule?" That's totally fine.
Negotiation is fucking complicated. It's a confusing blend of human psychology, business acumen, and confidence that a lot of people don't have -- that's why you hired a lawyer to "negotiate" with the judge after you ran that bus-full of kids off the road back in '98.
But basic negotiation is actually really simple. It's totally process-driven. If you can figure out (1) what you want, (2) what you're willing to accept, (3) and what you'll do if an agreement isn't reached, then you have everything you need to start negotiating stuff in your everyday life.
@@ -0,0 +1,49 @@
---
layout: post
title: "Create a Custom CollectionView for a macOS App in Swift"
categories:
- Tutorials
tags:
- swift
- coding
- macOS
last_modified_at:
excerpt_separator: <!-- more -->
---
1. Register CustomCollectionViewItem in the CustomViewController
2. Adopt NSCollectionViewDataSource in CustomViewController
3. Override `loadView()` in CustomCollectionViewItem
<!-- more -->
```swift
import Cocoa
class CustomViewController: NSViewController {
@IBOutlet weak var collectionView: NSCollectionView!
override func viewDidLoad() {
self.collectionView.register(CustomCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier("CustomCollectionViewItem"))
}
}
extension CustomViewController: NSCollectionViewDataSource {
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = self.collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier("CustomCollectionViewItem"), for: indexPath)
return item
}
}
class CustomCollectionViewItem: NSCollectionViewItem {
override func loadView() {
}
}
```
@@ -0,0 +1,20 @@
---
layout: post
title: "The Anatomy of iOS"
categories:
- Tutorials
tags:
- swift
- coding
- iOS
last_modified_at:
excerpt_separator: <!-- more -->
---
In my opinion, one of the hardest things to do do in programming is to start. The good thing about coding is: you have infinite resources available to you. It is awesome. The bad thing is: you have infinite resources available to you. It is horrible.
And most tutorials focus on teaching you the details first. They dive straight into code. They don't help to structure your thinking. I'll try to help with that a little bit, by providing an overview over the iOS anatomy. This article wants to provide an overview. To get the details, it links to Apple's documentation website.
<!-- more -->
@@ -0,0 +1,33 @@
---
layout: post
title: "Getting Your First App Into Apple's App Store"
categories:
- Tutorials
tags:
- English
- swift
- iOS
last_modified_at:
excerpt_separator: <!-- more -->
---
You have begun the journey to become an iOS developer. Great! This is an awesome decision. But now what? Where to start? You are in luck! There are many great tutorials out there that will help you get started. It really doesn't matter which one you pick. The important thing is: you have to stick with it for a while. I personally recommend [Hacking With Swift](https://hackingwithswift.com) by Paul Hudson. Start working on the teaching projects and code along. Until you feel like you know enough to start your own project. Then jump. Don't wait too long; don't get trapped in the tutorial trap.
<!-- more -->
This jump is hard. I guarantee you, that you will experience one thing: getting lost. Feeling overwhelmed. What now? You have that great app idea in your mind. You know exactly hoy it should look. What features it should support. But getting there is hard. Trust me. But it is **not** impossible. You need to be determined.
Even though you think everything is crystal clear, it really isn't -- yet. You will think about a feature and will soon realize: You have no idea how to go from the idea to the working product. Every technology you might need could become a hurdle that is hard to take. And you will also realize: most of the tutorials only teach you the real easy part: how to do some small thing, while imposing heavy constraints. However, the true difficulty in programming is not the coding. If you have a small task that is heavily constrained, everybody can do it.
The hard part about programming is decomposing a highly complex problems into these small tasks that everybody can implement. Your mind will have to work overtime to plant all these new connections and you will get lost. All. The. Time.
This guide will give you a guideline to not stay lost forever and get back on track quickly. It will help you reach the goal of every aspiring app developer: **getting your first app into the app store**.
Xcode-Gen: https://github.com/yonaskolb/XcodeGen
Swiftlint: https://github.com/realm/SwiftLint
Anmelden AppStore Connect
http://www.vadimbulavin.com/swift-code-style/
Create persistent Checklist
Git flow
Phased Release
Plan the Feedback phase
@@ -0,0 +1,42 @@
---
layout: post
title: "Erfahrungsbericht CORE Consulting Competition 2019"
categories:
- CCC19
tags:
- deutsch
last_modified_at:
excerpt_separator: <!-- more -->
---
Seit ich 2010 den ersten Fuß in das Büro von [Hanseatic Consulting](www.hanseaticconsulting.de) setzte, glüht mein Herz für Themen aus der Unternehmenberatung. Meine Favoriten sind: Strategie und Prozesse und Technologien -- IT -- , die beides miteinander verbinden. Und mein Herz brennt für **studentische** Unternehmenberatung. Das Konzept ist für mich absolut begeisternd.
Als dann Anfang des Jahres 2019 eine Einladung zur CORE Consulting Competition (CCC) reinflatterte, war mein Interesse geweckt. CORE ist ein Think Tank, der sich unter anderem mit _meinen_ Themen befasst. Die CCC ist ein Talentfindungswettbewerb von CORE, indem unterschiedliche studentische Beratungen gegeneinander antreten. Let's go.
<!-- more -->
## Bewerbung
Der Bewerbungsprozess war schmerzlos. Wir fanden uns als Team zusammen und haben via Google Docs ein Motivationsschreiben verfasst. Das ganze in ordentliche Form gegossen und ab dafür.
###Download hinzufügen
## Kick-off
Am 01. April ging es los. Einstiegs-Telefonkonferenz mit allen Beteiligten. Sowohl von CORE, als auch aus den Beratungen. Wie zu erwarten, wurde darin nicht viel kommuniziert. Der grobe Ablaufplan war auf den Slides, aber die Tonspur bot keinen großen zusätzlichen Mehrwert. Nachdem wir dann 9 Stunden später (!) endlich das Material erhalten haben, konnten wir anfangen daran zu arbeiten.
Im Material enthalten waren:
- Schulungsunterlagen zu: Projektmanagement, Powerpoint, Storytelling
- Case Study
- Fact Pack zur Case Study (Info-Material zum Markt, zur Branche, usw)
Das Material war sehr hochwertig, umfangreich und durchdacht und bietet eine wirkliche Herausforderung. Das Thema der Case Study bewegte sich im Sektor Banken und IT.
## Feedback
Feedback ist wichtig. Es hilft bei der persönlichen Weiterentwicklung und bei der Weiterwicklung von Organisationen. Hier ist mein persönliches Feedback an CORE:
1. Ich habe mich zu Beginn des Wettbewerbs etwas veralbert gefühlt. Der Starttermin stand fest, man hat sich Zeit für das erste Telefonat genommen; aber dann war die Informationsdichte des Telefonats fast gleich 0. Die Wahl des Mediums war aus meiner Sicht verfehlt. Eine einfache Email hätte das Verarbeiten der Informationen wesentlich beschleunigt.
2. Die Einstiegs-Email mit dem Case-Study-Material war zum Wettbewerbsbeginn nicht fertig. Das darf mMn nicht sein. Der Start-Termin steht lange im Voraus fest. Wir haben uns für 10 Uhr Zeit genommen, in der Erwartung, dass wir loslegen können. Wir mussten bis 19 Uhr warten, bevor uns das Material vorlag. Wenn ein solcher Wettbewerb ausgerichtet wird, sollte die Timeline und das nötige Material vorliegen.
@@ -0,0 +1,23 @@
---
layout: post
title: "Short Introduction to JavaFX"
categories:
- Tutorials
tags:
- English
- Java
- JavaFX
- Swift
- macOS
last_modified_at:
excerpt_separator: <!-- more -->
---
| General Term | Swift | JavaFX |
| ------------ | -------- | ----------------------------------------------------------------------------------------- |
| Window | NSWindow | **Stage**: A stage can display one Scene at a time, but you can change Scenes at runtime. |
| Content Area | NSView | **Scene**: A Scenes has a Scene graph consisting of Nodes. |
| Layout | | **Layouts** or **Partents**: Layouts are a way to structure the element within a Scene. |
| UI Elements | | **Controls**: Controls are things like Buttons, Sliders, etc. |
@@ -0,0 +1,13 @@
---
layout: post
title: "A Publish Homepage"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
https://github.com/johnsundell/publish
@@ -0,0 +1,15 @@
---
layout: post
title: "Fitness"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
https://old.reddit.com/r/bodyweightfitness/wiki/kb/recommended_routine
https://old.reddit.com/r/bodyweightfitness/comments/6talge/split_routines_tend_to_be_suboptimal_for_beginners/
https://old.reddit.com/r/bodyweightfitness/comments/gpnigl/things_i_know_now_after_doing_the_recommended/
@@ -0,0 +1,24 @@
---
layout: post
title: "My Emacs Journey to Org-Mode"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Emacs is a journey. [^1]
[^1]: https://github.com/d12frosted/homebrew-emacs-plus
If you are studying computer science, you have probably heard of text editors and maybe even about the editor wars. There is a myriad of te
https://www.youtube.com/watch?v=JWD1Fpdd4Pc
https://www.youtube.com/watch?v=oJTwQvgfgMM
https://github.com/magit/magit
https://orgmode.org/
@@ -0,0 +1,15 @@
---
layout: post
title: "Progressive Disclosure"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
https://en.wikipedia.org/wiki/Progressive_disclosure
https://youtu.be/oJTwQvgfgMM?t=2455
@@ -0,0 +1,26 @@
---
layout: post
title: "Install Searx on Uberspace 7"
categories:
- Tutorials
tags:
- English
- email
- searx
- mailinglist
- software
- self-hosted
- tutorial
last_modified_at:
excerpt_separator: <!-- more -->
---
This tutorial explains how to install [SearX](https://github.com/asciimoo/searx) on a [Uberspace 7](uberspace.de).
<!-- more -->
------------------------------------------------------------------------
Tested on Uberspace v7.7.0 with NodeJS v12 and MariaDB 10.3.23.
@@ -0,0 +1,60 @@
---
layout: post
title: "Useful Snippets For macOS"
categories:
- Tutorials
tags:
- English
- software
- cli
last_modified_at:
excerpt_separator: <!-- more -->
---
<!-- more -->
## Convert an ISO to IMG
```
hdiutil convert -format UDRW -o \~/path/to/target.img \~/path/to/ubuntu.iso
diskutil list
diskutil unmountDisk /dev/diskN
sudo dd if=IMAGE.img of=/dev/diskN bs=1m
diskutil eject /dev/diskN
```
## Copy a file to the clipboard from the Terminal
`cat ~/.bashrc | pbcopy`
## Dock settings
```
defaults write com.apple.dock no-bouncing -bool TRUE
defaults write com.apple.dock autohide-delay -int 0
defaults write com.apple.dock autohide-time-modifier -float 0.4
killall Dock
```
## Remove all DS_Store files globally to reset Finder view settings
`sudo find / -name ".DS\_Store" -exec rm {} \;`
## SSH
### Generate key
`ssh-keygen -t rsa -b 4096`
### Add key to ssh-agent (-K to permanently add)
`ssh-add -K ~/.ssh/~<NAME OF KEY>~`
### List added identities
`ssh-add -l`
### Use specific port
`ssh -p 3022 user@localhost`
## Pinboard.in: Add Bookmark to specific tag (Bookmarklet)
```
javascript:q=location.href;if(document.getSelection){d=document.getSelection();}else{d='';};p=document.title;void(open('https://pinboard.in/add?later=yes&noui=yes&jump=close&tags=TAGS GO HERE&url='+encodeURIComponent(q)+'&description='+encodeURIComponent(d)+'&title='+encodeURIComponent(p),'Pinboard','toolbar=no,width=100,height=100'));
```
@@ -0,0 +1,122 @@
---
layout: post
title: "Create a Telegram Bot"
categories:
- Code
tags:
- English
- software
last_modified_at:
excerpt_separator: <!-- more -->
---
I like [Telegram](https://telegram.org). Even though it **absolutely _cannot_ be recommended** if you need security and privacy---I can't stress this enough: Telegram **is not secure**---, it offers very nice, fast and convenient features. One feature I particularly like are stickers. They basically are over sized emoji that give artists a lot of freedom to express emotion. These stickers are collected in sets that can be added to your client. Look at this cool Dino:
<video controls>
<source src="/img/20200827-dino.mp4" type="video/mp4">
</video>
They have one problem: Many times a sticker set has only a few really good stickers.
To get around this problem Telegram offers a system to collect favorite stickers. This is a very good idea. But only in theory. The clients implement a very confusing design decision (or is it a bug?). The list of favorites is only 5 stickers wide; and the moment you add another sticker, the oldest one gets pushed into nothingness. 5 favorites are not enough.
There are two solutions to this problem: 1) Contribute to the source code of Telegram and try to fix this bug, 2) Create a Telegram bot, that can curate a personal sticker collection.
Since I participated in the GitHub repository of Telegram in the past and it wasn't a good experience, I decided to try myself on a Telegram Bot. This way, I am not reliant on anybody and I can learn something in the meanwhile.
<!-- more -->
## The Goal
Creating a bot. Send a sticker to the bot and it puts it in a curated set; curated by the user. Ultimately this makes it possible to only be subscribed to a personal sticker set that contains all favorite stickers of the user.
## Preparation
### First Decisions
The first step for any project is reading available documentation to better understand the problem space. Luckily, the [Telegram Bots API](https://core.telegram.org/bots/api) is very well documented. It also contains a [comprehensive list of Bot API implementations](https://core.telegram.org/bots/samples).
I decided to use the programming language Java for the bot implementation, since I am most comfortable with it. I will use [rubenlagus's TelegramBots](https://github.com/rubenlagus/TelegramBots) API implementation. The *test* bot will be hosted on my Raspberry Pi, the *production* bot on my [Uberspace](https://uberspace.de).
### Telegram API Overview
To identify and understand how to use the API, my first step is looking through the [available types](https://core.telegram.org/bots/api#available-types). The types and attributes of interest are:
- User:
- id (necessary to attribute the sticker set)
- username (to construct the sticker set name)
- Chat:
- id (to respond to the correct chat, post status messages, etc.)
- Message:
- message_id
- from -> Returns the User (see above)
- chat -> Returns the Chat (see above)
- reply_to_message (reply to the posted sticker), text (a field where we can receive text and communicate with the user)
- sticker -> Returns a/the Sticker (see below)
- BotCommand:
- command
- description
- Sticker:
- file_id
- is_animated -> Important, since regular and animated stickers can't be in the same set
It seems to be possible to extract the required information from the Message object. However, there are limits to the sticker sets: 50 in animated sticker sets and 120 in unanimated sets. Once we reach the limit, we need to create a new set. This means we need to somehow keep state or have the user keep track of it.
### Understanding the Connection to the Java Implementation
After adding all required dependencies, the entry point of the Java API looks like this:
```java
public class Main {
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
telegramBotsApi.registerBot(new FavoriteStickersBot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
```
We initialize the API implementation and then we register our custom `FavoriteStickersBot` class with it. There are different ways to implement a bot, but we will go with the *Getting Started* way and extend `TelegramLongPollingBot`. [Long polling](https://en.wikipedia.org/wiki/Push_technology#Long_polling) is a method that enables the system to use push behavior without actually having push capabilities.
```java
public class FavoriteStickersBot extends TelegramLongPollingBot {
public String getBotUsername() {
return BotConfig.BOT_USERNAME;
}
public String getBotToken() {
return BotConfig.BOT_TOKEN;
}
public void onUpdateReceived(Update update) {}
```
When running the program, the bot will execute and
The Java implementation basically uses a 1:1 mapping of the API to Java. To instantiate a Telegram User object you can either use `User user = new User()` and then use the setters
Methods are implemented the similarly. To create a new sticker set we do the following:
```java
CreateNewStickerSet createNewStickerSet = new CreateNewStickerSet()`. We then
```
## Implementation
### Project setup
Following the [Getting Started Guide](https://github.com/rubenlagus/TelegramBots/wiki/Getting-Started) from TelegramBots, the first step is registering your new and shiny bot with the Telegram [@BotFather](https://telegram.me/BotFather). During this process you will receive the required API token to enable communication between the bot and the Telegram service.
## Potential Pitfalls
I am using the file_id instead of creating the stickers from scratch
## Next Steps
Currently, the bot is single-user only. It should be reasonably easy to add multi-user support by creating a group, adding the bot to it and then having a shared best sticker set.
@@ -0,0 +1,17 @@
---
layout: post
title: "Explore Bitcoin Core Codebase"
categories:
- Programming
tags:
- English
- Software
last_modified_at:
excerpt_separator: <!-- more -->
---
Using SourceTrail, a program that helps with exploring code
Build Bitcoin yourself
https://github.com/bitcoin/bitcoin/blob/master/doc/build-osx.md
@@ -0,0 +1,19 @@
---
layout: post
title: "Bewerbungsprozess"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
## C.A.R.
Context: What situation were you in? What background information does the listener need to understand the context? What was the task you were expected to perform? What needed to be done? What challenges did you expect to face?
Action: What actions did you take? (You can also outline what alternatives you considered.)
Result: What impact did your actions have? (These do not have to be all puppies and rainbows. You can admit that you got it wrong on the first try and had to go back and fix something.)
## S.T.A.R.
Situation, Task, Action, Result.
@@ -0,0 +1,15 @@
---
layout: post
title: "Running my own D&D Group"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
https://www.dnd-compendium.com/dm-resources/adventure-guides/lost-mine-of-phandelver
https://www.youtube.com/watch?v=w5xnrxIOSYs&list=PLb39x-29puap4Bdz3vC5ci39V0E8O7n4S&index=2&t=0s
https://dungeonmaster.academy/articles/running-the-lost-mine-of-phandelver
@@ -0,0 +1,29 @@
---
layout: post
title: "Better Education Initiative"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
University is awesome. But the way it has developed in the last few years is awful. University should not be like school. Join the Better Education Initiative and let's make university great again KEKW
## Manifesto
### No cramming
### Practice makes perfect
### Rework grading
## Maths
### Unify symbols
### Central hub for tests and exercises
Lehrende wollen manchmal "nur prüfen"
@@ -0,0 +1,31 @@
---
layout: post
title: "Here is the Plan"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Working on your own is hard. Corona does not make it easier. My Bachelor's thesis is done. Now onto the next step. Here is the plan. <!-- more -->
- Need
Accountability
I need a plan. Here is an attempt.
Order of operations
Programming
Uni
Personal
https://teachyourselfcs.com/
https://jordanlewis.org/posts/twitch-live-coding/
@@ -0,0 +1,28 @@
---
layout: post
title: "Setup and Use Dynamic DNS"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Clone unbound via https https://github.com/NLnetLabs/unbound
install bind:
download version without libuv (9.11.21)
download source
$ sh autogen.sh
$ ./configure --with-openssl --enable-threads --prefix=$HOME
$ make
$ make check
$ make install
named should be installed in ~/sbin/
@@ -0,0 +1,15 @@
---
layout: post
title: "About Unimportant Things"
categories:
- Personal
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
I just ran into a few inconveniences in my text editor Sublime Text. It stumbles on various Markdown issues which can become annoying. For example when the formatting of fenced code blocks in a specific programming language (in my case Java) bleeds into the rest of the text and stylized it in a way which makes it hard to work with. I decided to give VS Code another go, because it is a *great* editor. And its ecosystem is insane; being backed by the horrible, but vast node.js community.
And then it started. Configuring an editor to personal preference always runs into topics like "Tabs vs. Spaces". These topics consume so much energy, it is actually ridiculous.
@@ -0,0 +1,3 @@
<div class="alert alert-{{ include.style }}" role="alert">
{{ include.content }}
</div>
@@ -0,0 +1,6 @@
{% if page.comments != false %}
<section>
<h2>Comments</h2>
</section>
{% endif %}
@@ -0,0 +1,4 @@
<p>
&copy; {{ site.time | date: '%Y' }}.
<a href="{{ "/LICENSE.md" | relative_url }}">MIT License.</a>
</p>
@@ -0,0 +1,5 @@
{% if post.last_modified_at %}
<span class="badge bg-secondary">{% octicon sync height:12 class:"" %} {{ post.last_modified_at | date: "%Y-%m-%d" }}</span>
{% else %}
<span class="badge bg-secondary">{{ post.date | date: "%Y-%m-%d" }}</span>
{% endif %}
@@ -0,0 +1,2 @@
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{{ "/favicon.png" | relative_url }}" />
<link rel="shortcut icon" href="{{ "/favicon.png" | relative_url}}" />
@@ -0,0 +1,26 @@
<head>
<link href="https://gmpg.org/xfn/11" rel="profile" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<!-- Enable responsiveness on mobile devices-->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
<title>
{% if page.title == "Home" %}
{{ site.title }}{% if site.tagline %} &middot; {{ site.tagline }}{% endif %}
{% else %}
{{ page.title }} &middot; {{ site.title }}
{% endif %}
</title>
<!-- CSS -->
<link rel="stylesheet" href="{{ "/assets/css/main.css" | relative_url }}" />
<!-- Icons -->
{% include favicons.html %}
<!-- RSS -->
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ site.feed.path | default: 'feed.xml' | relative_url }}" />
</head>
@@ -0,0 +1,5 @@
<header class="row py-3">
<div class="col">
<h1 class="display-1">{{ page.title }}</h1>
</div>
</header>
@@ -0,0 +1,17 @@
{% comment %}
Dynamically generate list of links to all category pages
{% endcomment %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-expanded="false">Categories</a>
<ul class="dropdown-menu">
{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}
{% for node in pages_list %}
{% if node.title != null %}
{% if node.layout == "category" %}
<li><a class="dropdown-item {% if page.url == node.url %} active{% endif %}" href="{{ node.url | relative_url }}">{{ node.title }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
</li>
@@ -0,0 +1,33 @@
<nav class="navbar navbar-dark bg-dark navbar-expand-md ">
<div class="container-fluid">
{% if site.sidebar_home_link %}
<a class="nav-link navbar-brand {% if page.url == '/' %} active{% endif %}" href="{{ "/" | relative_url }}"><img src="/favicon.png" width="30" height="30" alt=""> </a>
{% endif %}
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation-toggle" aria-controls="navigation-toggle" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navigation-toggle">
<div class="navbar-nav">
{% include nav/tags.html %}
{% comment %}
The code below dynamically generates a sidebar nav of pages with
`sidebar_link: true` in the front-matter. See readme for usage.
{% endcomment %}
{% include nav/pages.html %}
{% include nav/categories.html %}
{% if tags_page %}
<a class="nav-link{% if page.url == '/tags' %} active{% endif %}" title="Tags" aria-label="Tags" href="{{ tags_page.url | relative_url }}">Tags</a>
{% endif %}
<a class="nav-link" title="Subscribe" aria-label="Subscribe" href="{{ site.feed.path | default: 'feed.xml' | relative_url }}">RSS</a>
{% if site.author.flair %}
<span>{{ site.author.flair }}</span>
{% endif %}
</div>
</div>
</div>
</nav>
@@ -0,0 +1,8 @@
{% assign pages_list = site.pages|sort:"sidebar_sort_order" %}
{% for node in pages_list %}
{% if node.title != null %}
{% if node.sidebar_link %}
<a class="nav-link{% if page.url == node.url %} active{% endif %}" href="{{ node.url | relative_url }}">{{ node.title }}</a>
{% endif %}
{% endif %}
{% endfor %}
@@ -0,0 +1,9 @@
{% comment %}
Check if we have tag or search pages page active before linking to it.
{% endcomment %}
{% assign tags_page = false %}
{% for node in site.pages %}
{% if node.layout == "tags" %}
{% assign tags_page = node %}
{% endif %}
{% endfor %}
@@ -0,0 +1,48 @@
{% if paginator.total_pages > 1 %}
<nav aria-label="page navigation">
<div class="row">
<div class="col">
<ul class="pagination justify-content-center">
{% if paginator.previous_page %}
<li class="page-item">
<a class="page-link" href="{{ paginator.previous_page_path | relative_url }}">&larr;</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">&larr;</a>
</li>
{% endif %}
{% for page in (1..paginator.total_pages) %}
{% if page == paginator.page %}
<li class="page-item active" aria-current="page">
<span class="page-link">
{{ page }}
</span>
</li>
{% elsif page == 1 %}
<li class="page-item">
<a class="page-link" href="{{ '/' | relative_url }}">{{ page }}</a>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="{{ site.paginate_path | relative_url | replace: ':num', page }}">{{ page }}</a>
</li>
{% endif %}
{% endfor %}
{% if paginator.next_page %}
<li class="page-item">
<a class="page-link" href="{{ paginator.next_page_path | relative_url }}">&rarr;</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1" aria-disabled="true">&rarr;</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
{% endif %}
@@ -0,0 +1,33 @@
<div class="card-subtitle mb-2 text-muted">
{% if include.post.last_modified_at %}
<span class="">{{ include.post.date | date: "%Y-%m-%d" }}</span> &bull;
<span class="">{% octicon sync height:12 class:"" %} Updated: {{ include.post.last_modified_at | date: "%Y-%m-%d" }}</span>
{% else %}
<span class="">{{ include.post.date | date: "%Y-%m-%d" }}</span>
{% endif %}
<span class="post-categories">
{% for category in include.post.categories %}
&bull;
{% comment %}
Check if this category has a corresponding page before decide
to link to it. This is an O(n^2) operations so consider removing
it and linking for all categories (or no categories) if this
site has a lot of pages and/or a lot of categories.
{% endcomment %}
{% assign category_page = false %}
{% for node in site.pages %}
{% if node.category == category or node.title == category %}
{% assign category_page = node %}
{% endif %}
{% endfor %}
{% if category_page %}
<a href="{{ category_page.url | relative_url }}">{{ category_page.title | default: category_page.category }}</a>
{% else %}
{{ category }}
{% endif %}
{% endfor %}
</span>
</div>
@@ -0,0 +1,15 @@
<div class="py-3">
{% comment %}
Check if we have a tags page active before linking to it.
{% endcomment %}
{% assign tags_page = false %}
{% for node in site.pages %}
{% if node.layout == "tags" %}
{% assign tags_page = node %}
{% endif %}
{% endfor %}
{% for tag in include.post.tags %}
{% if tags_page %}<a href="{{ tags_page.url | relative_url }}#{{ tag | slugify }}">{% endif %}<span class="btn btn-sm btn-secondary">{% octicon tag height:12 class:"" %} {{ tag }}</span>{% if tags_page %}</a>{% endif %}
{% endfor %}
</div>
@@ -0,0 +1,11 @@
<section>
<h2>Related Posts</h2>
<ul>
{% for post in site.related_posts limit:3 %}
<li>
<a href="{{ post.url | relative_url }}"> {{ post.title }}</a>
{% include date-badges.html %}
</li>
{% endfor %}
</ul>
</section>
@@ -0,0 +1,25 @@
<div class="">
<h3 class="">
<a href="{{ repository.html_url }}">
{{ repository.name }}
</a>
</h3>
<div>
{{ repository.description }}
</div>
<div>
{% if repository.stargazers_count %}
<span class="">
<svg style="fill: #767676" class="octicon octicon-star" viewBox="0 0 14 16" version="1.1" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z"></path></svg>
{{ repository.stargazers_count }}
</span>
{% endif %}
{% if repository.forks_count %}
<span class="">
<svg style="fill: #767676" octicon octicon-git-branch" viewBox="0 0 10 16" version="1.1" width="10" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"></path></svg>
{{ repository.forks_count }}
</span>
{% endif %}
</div>
</div>
@@ -0,0 +1 @@
<script src="{{ "/assets/js/bootstrap.min.js" | relative_url }}" crossorigin="anonymous"></script>
@@ -0,0 +1,18 @@
---
layout: page
---
{% unless page.content == '' %}
{{ content }}
{% endunless %}
<ul class="posts-list">
{% assign category = page.category | default: page.title %}
{% for post in site.categories[category] %}
<li>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
{% include date-badges.html %}
</li>
{% endfor %}
</ul>
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en-us">
{% include head.html %}
<body class="{{ page.layout }}{% if page.url == '/' %} home{% endif %}">
{% include nav/navigation.html %}
<main class="container py-3">
{% include header.html %}
{{ content }}
</main>
<footer class="container-fluid py-3">
{% include pagination.html %}
{% include scripts.html %}
</footer>
</body>
</html>
@@ -0,0 +1,53 @@
---
layout: default
---
<div class="row">
<div class="col">
{% for post in paginator.posts %}
<div class="pb-5">
<div class="card bg-dark p-2">
<div class="card-body">
<h2 class="card-title">
<a href="{{ post.url | relative_url }}">
{{ post.title }}
</a>
</h2>
<div class="card-text">
{% include post-meta.html post=post %}
{% if post.excerpt %}
{{ post.excerpt }}
{% else %}
{{ post.content }}
{% endif %}
{% if post.excerpt %}
{% comment %}Excerpt may be equal to content. Check.{% endcomment %}
{% capture content_words %}
{{ post.content | number_of_words }}
{% endcapture %}
{% capture excerpt_words %}
{{ post.excerpt | number_of_words }}
{% endcapture %}
</div>
{% if content_words != excerpt_words %}
<a href="{{ post.url | relative_url }}" class="btn btn-sm btn-secondary">
Read more {% octicon chevron-right height:12 %}
</a>
{% endif %}
{% endif %}
</div>
</div>
</div>
{% endfor %}
<!-- end of paginator -->
</div>
</div>
@@ -0,0 +1,9 @@
---
layout: default
---
<div class="row">
<div class="col">
{{ content }}
</div>
</div>
@@ -0,0 +1,16 @@
---
layout: default
---
<div class="row">
<div class="col">
{% include post-meta.html post=page %}
<div>
{{ content }}
</div>
{% include post-tags.html post=page %}
{% include related_posts.html %}
</div>
</div>
@@ -0,0 +1,19 @@
---
layout: default
---
<div class="row">
<div class="col">
{{ content }}
<div>
{% for repository in site.github.public_repositories limit: 100 %}
{% if repository.stargazers_count > 0 %}
<div>
{% include repo-card.html %}
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
@@ -0,0 +1,37 @@
---
layout: default
---
<!-- See https://blog.lanyonm.org/articles/2013/11/21/alphabetize-jekyll-page-tags-pure-liquid.html -->
<!-- With added pipe to handle lack of sort_natural -->
{% capture site_tags %}{% for tag in site.tags %}{{ tag | first | downcase }}|{{ tag | first }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
<!-- site_tags: {{ site_tags }} -->
{% assign tag_words = site_tags | split:',' | sort %}
<!-- tag_words: {{ tag_words }} -->
<div class="row">
<div class="col-md-3">
<div class="btn-group-vertical">
{% for tag_pair in tag_words %}
{% assign tag = tag_pair | split:'|' | last %}
<a href="#{{ tag | slugify }}" class="btn btn-sm btn-secondary">{% octicon tag height:12 class:"" %} {{ tag }}: {{ site.tags[tag] | size }}</a>
{% endfor %}
</div>
</div>
<div class="col">
{% for tag_pair in tag_words %}
{% assign tag = tag_pair | split:'|' | last %}
<div id="{{ tag | slugify }}" class="posts-for-tag">
<h2>{{ tag }}</h2>
<ul>
{% for post in site.tags[tag] %}
<li>
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
{% include date-badges.html %}
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
</div>
@@ -0,0 +1,137 @@
---
layout: post
title: "Install Syncthing on Uberspace 6 in a Subdomain"
categories:
- Tutorials
tags:
- English
- Self-Hosted Software
last_modified_at: 2020-07-18
excerpt_separator: <!-- more -->
---
<div class="alert alert-warning">
<h2 class="alert-heading">Uberspace 6 has reached <a href="https://en.wikipedia.org/wiki/End-of-life_(product)">EOL</a></h2>
<p>If you want to use Syncthing, you should create an Uberspace 7 and refer to the the <a href="https://lab.uberspace.de/guide_syncthing.html">Syncthing tutorial from the Uberlab</a>!</p>
</div>
This short tutorial explains how to install [Syncthing](https://syncthing.net) on a [Uberspace](https://uberspace.de). It is based on the [~~Tutorial~~](https://maxhaesslein.de/dachboden/syncthing-auf-uberspace/) from [Max Haesslein](http://maxhaesslein.blog). Thanks Max!
<!-- more -->
## Download newest Syncthing version
Connect to your uberspace:
```
ssh <user>@<uberspace>
```
Download the [newest Syncthing version](https://github.com/syncthing/syncthing/releases/latest) for Linux:
```
cd ~/etc/
wget <NEWEST AMD64 LINUX VERSION>
```
Extract the file (eXtract Ze Files!) and move it to its own folder:
```
tar -xzf <FILENAME>
mv <FOLDERNAME> syncthing/
```
Link it to your binaries folder and start it once:
```
ln -s ~/etc/syncthing/syncthing ~/bin/syncthing
syncthing
```
Close the program with CTRL-C.
## Prepare your Uberspace
Get the ports we are going to use for GUI and sync:
```
uberspace-add-port -p tcp --firewall
🚀 All good! Opened tcp port <PORT1>.
uberspace-add-port -p both --firewall
🚀 All good! Opened tcp port <PORT2>.
```
Add a subdomain to make your Syncthing easily accessible; also make sure it is possible to connect through HTTPS:
```
uberspace-add-domain -w -d sync.<DOMAIN>.de
uberspace-letsencrypt
uberspace-letsencrypt-renew -f
```
If you already use LetsEncrypt, you have to add the domain to your configuration. Just follow the steps displayed after the `uberspace-letsencrypt`. Don't forget to add the subdomain to your domain registrar DNS records aswell, so it gets redirected correctly!
Now, create the corresponding folder on the Uberspace:
```
mkdir /var/www/virtual/<UBERSPACE>/sync.<DOMAIN>.de
```
Edit the `.htaccess` so it sends you to the correct port:
```
cd /var/www/virtual/<UBERSPACE>/sync.<DOMAIN>.de/
vim .htaccess
```
```
RewriteEngine On
RewriteRule (.*) http://localhost:<PORT1>/$1 [P]
```
## Modify the Syncthing config file
Open the syncthing config file:
```
cd ~/.config/syncthing
vim config.xml
```
Find the GUI entry and replace the port with `<PORT1>`:
```
...
<gui enabled="true" tls="false" debugging="false">
<address>127.0.0.1:<PORT1></address>
...
```
Find the options entry and replace the port with `<PORT2>`:
```
...
<options>
...
<localAnnouncePort><PORT2></localAnnouncePort>
<localAnnounceMCAddr>[ff12::8384]<PORT2></localAnnounceMCAddr>
...
```
## Setup Syncthing as a service
If you don't have any services running, you have to setup the Daemon Tools first: [Uberspace Wiki, Daemon Tools](https://wiki.uberspace.de/system:daemontools).
After setting up the services, you can add Syncthing as a service and restart it once:
```
uberspace-setup-service syncthing ~/bin/syncthing
svc -du ~/services/syncthing
```
## Secure your Syncthing instance
Your Syncthing is now available via `sync.<DOMAIN>.de`. However, it is accessible by everyone on the web. Therefore you should secure it. Got to the Syncthing Settings:
![You can access your settings via Actions -> Settings](/img/20180602-Syncthing-settings.png)
**IMPORTANT: Do not check `Use HTTPS for GUI` you will lose access to your GUI. To get it back you have to find the TLS option in your Syncthing config and set it to `false` again. You connections will have TLS and will be secure without checking this box.**
And now enter your admin user and password in the corresponding fields:
![You can access your settings via Actions -> Settings](/img/20180602-Syncthing-settings2.png)
## The end
Save and that's it! You now have a Syncthing service running on Uberspace! Ideal for private documents you don't want the NSA to have.
@@ -0,0 +1,85 @@
---
layout: post
title: "Zusammenfassung von Fredmund Maliks Führen, Leisten, Leben"
categories:
- Summaries
tags:
- Deutsch
- Philosophy
last_modified_at:
excerpt_separator: <!-- more -->
---
[Fredmund Maliks](https://de.wikipedia.org/wiki/Fredmund_Malik) [Führen, Leisten, Leben](https://www.amazon.de/dp/3593501279/) ist ein Management-Standardwerk. Es schildert wichtige Aspekte des Managements und die Philosophie des Autors. Dabei steht vor allem eine These im Zentrum: Gutes Management kann man lernen und ist **keine** gottgegebene Fähigkeit. Das Buch legt dar, wie man diese Fähigkeit lernen kann. Ich habe das Buch gelesen und für Dich zusammengefasst.
<!-- more -->
## Der Manager
* Der Manager ist eine der wichtigsten Personen in der modernen Gesellschaft, da die Schnittstellen zwischen Berufen immer größer und das Leben immer schneller wird.
* Der Manager muss als Organisation denken. Er ist Teil eines größeren Komplex und trägt zu der Wirksamkeit und zum Erfolg der Gesamtheit bei.
* Wie bei vielen Berufen, wird Exzellenz als Manager durch Üben erzielt. Dabei spielt Talent zwar eine große Rolle: nur wer Talent mitbringt kann Management beherrschen. Aber prinzipiell kann **jeder** solide Management-Erfolge erzielen.
## Management-Prinzipien
Die wichtigsten Grundprinzipien der wirksamen und qualitativ wertvollen Führung sind:
* Resultat- und Zielorientierung
* Das Denken als Organisation und der Beitrag zum Ganzen
* Fokussierung auf einige wenige wichtige Punkte und Herausdestillieren dieser Punkte: Fokus!
* Stärken-Denken und nicht Schwächen-Denken, wie es in der Gesellschaft üblich ist: Stärken stärken!
* Positives Denken und Chancen-Fokus, nicht Problem-Fokus
* Vertrauen und Integrität, also z.B. Schutz der Mitarbeiter nach außen und oben und nicht Beschmücken mit fremder Leistung
* Kontrollieren, aber auch mal *fünfe gerade sein lassen*; Kontrolle basiert auf Vertrauen
* Individuelle Förderung der Mitarbeiter
## Führung einer Organisation
* Zur Umsetzung dieser Art der Führung:
* Arbeiten mit Zielen (unbürokratisch!) und auch (persönlichen) Jahreszielen
* Effiziente Organisation und vermeiden von zu viel “Organisitis”; aber nicht jedes Problem durch Neu-Organisation lösen, wenn es nicht dadurch zu lösen ist
* Die drei Grundfragen der Organisation:
1. Wie müssen wir uns organisieren, damit das, wofür der **Kunde** uns bezahlt, im Zentrum der Aufmerksamkeit steht und von dort nicht wieder verschwinden kann?
2. Wie müssen wir uns organisieren, damit das, wofür wir unsere **Mitarbeiter** bezahlen, von diesen auch wirklich getan werden kann?
3. Wie müssen wir uns organisieren, damit das, wofür die Firmenspitze/das Top-Management, bezahlt wird, von diesem auch wirklich getan werden kann?
* Zeichen schlechter Organisation:
* Zu viele, unnötige Managementebenen
* Zu viel bereichsübergreifende Arbeit: eine Organisation funktioniert dann am besten, wenn man so wenig wie nötig bereichsübergreifend arbeiten muss
* Zu viele Sitzungen, zu viele Leute
* Zu viele Arbeiter auf Projekten; am effizientesten ist es, wenn ein kompetenter Mitarbeiter ungestört arbeiten kann
* Zu viele Koordinatoren und Assistenten
* Umfokussierte Jobs
## Entscheidungen richtig treffen
Fundierte Entscheidungen treffen, dabei die Schlüssel-Spieler in den Prozess mit einbeziehen (dabei aber nicht aus Wohlwollen berücksichtigen, sondern nur aufgrund von tatsächlicher Wichtigkeit im Rahmen der Entscheidung!).
Der Entscheidungsprozess:
1. Die präzise Bestimmung des Problems
2. Die Spezifikation der Anforderungen, die die Entscheidung erfüllen muss
3. Das Herausarbeiten aller Alternativen
4. Die Analyse der Risiken und Folgen für jede Alternative und die Festlegung der Grenzbedingungen
5. Der Entschluss selbst
6. Der Einbau der Realisierung in die Entscheidung
7. Die Etablierung von Feedback, inklusive Follow-up und Follow-through
## Führungswerkzeuge
* **Die Sitzung:** davon nicht zu viele (s.o.), die Sitzungen nacharbeiten und bei den Verteilten Aufgaben auch Nachfassen (Follow-up)!
* Man sollte sich die Typen von TOP klarmachen und vorher überlegen, wie man mit ihnen umgeht:
* Echte Standards (die wichtigsten Punkte die besprochen werden müssen).
* Dauerbrenner (wiederkehrende Themen, die man nicht richtig lösen kann, z.B. Probleme beim Betriebsklima): Sollte man langfristig nicht dulden; Lösung finden ist das A und O.
* Verschiedenes am Ende aller TOP: Sollte man nicht dulden; ist politisches Instrument, ggf. sogar um ein Thema “durchzudrücken”.
* Jeder TOP sollte auch eine Aktion beinhalten; ist das nicht der Fall, verkommt die Sitzung schnell zur “Laber-Runde”
* Protokolle wo nötig (ggf. gesetzlich vorgeschrieben); wo optional: sinnvolles Protokoll-Führen (z.B. die Aufgabenverteilung dokumentieren, um sie als Follow-up-Mittel zu verwenden)
* **Der Bericht:** der schriftliche Bericht ist das effizientes Mittel der Daten-Kommunikation. Der Bericht muss wirksam sein! Daher sollte Zielgruppen-orientiert gearbeitet (z.B. der Bericht geht an einen Juristen: Fokus auf Text, an einen Ingenieur: Fokus auf Grafiken und Statistik), auf realistische Struktur geachtet werden und der Bericht sollte keine unnötigen Inhalte enthalten
* **Job Design, Assignment Control:** Jobs sollten gut definiert werden. Nicht zu großer, nicht zu kleiner Aufgabenspielraum. Vermeiden von Unnötigkeiten. Und Positionen sollten nicht starr sein, sondern eine Möglichkeit der Weiterentwicklung der Arbeitsstelle (in diesem Fall nicht zwingend des Mitarbeiters!) haben. Ist eine bestimmte Position oder Aufgabe nicht mehr notwendig, muss sie überführt/abgeändert werden.
* **Budget und Budgetierung:** das wichtigste Tool eines Managers. Richtig benutzt, lässt sich darüber alles steuern. Auch Zeit-, Innovations-, Worst-Case-Budgets benutzen! Ggf. erweitern! Idee des Budgets: Ich habe limitierte Ressourcen, diese sinnvoll verteilen. Weiterführende Schlagworte: Zero-Base-Budgeting, Life-Cycle-Budgeting
* **Leistungsbeurteilung:** Möglichst nicht standardisieren.
* **Systematische Müllabfuhr:** Regelmäßige Reviews und überlegen, was noch notwendig ist und was nicht. Unnötiges ausmerzen! In allen Bereichen des Unternehmens.
* **Persönliche Arbeitsmethodik:** Man sollte sich angewöhnen, sie regelmäßig auf Wirksamkeit zu überprüfen. Wenn man in der Position ist zu delegieren, sollte man das nutzen. Ist hochgradig individuell.
@@ -0,0 +1,47 @@
---
layout: post
title: "Basic Things to Consider When Starting an Online Business"
categories:
- Summaries
tags:
- English
- Checklist
last_modified_at: 2019-03-25
excerpt_separator: <!-- more -->
---
This post is a really short excerpt from a flyer I found a while ago. It lists thing you should consider, if you want to try to start an online business. Think about it as a checklist.
<!-- more -->
## Fundamental rules
- You must care about it.
- You must be able to become the authority on it.
- You must be able to differentiate yourself.
- You must fulfill a need.
- Your niche must be commercial.
## Ways to make money
- Affiliate marketing.
- Advertising.
- Selling your own products.
- Drop shipping (white labeling) - offer products redirect order to supplier.
## Setup process
- Deciding on a decent name for your online business.
- Registering your domain name, web hosting, and installing WordPress.
- Designing your website & logo.
- Registering social media profiles.
- Creating an online store.
- Setting up advertising, affiliate, and merchant accounts.
- Setting up Google Analytics.
## Necessary systems
- A system for getting attention (Venture Harbour, What Is My Comfort Zone, FanDistro).
- A system for capturing data.
- A system for selling products.
@@ -0,0 +1,29 @@
---
layout: post
title: "Use Picture-in-Picture Mode on Mac and iPad with a Bookmarklet"
categories:
- Tips
tags:
- English
- Apple
last_modified_at: 2020-07-20
excerpt_separator: <!-- more -->
---
[Quinn](https://twitter.com/SnazzyQ) from [Snazzy Labs](https://www.youtube.com/channel/UCO2x-p9gg9TLKneXlibGR7w) just posted an [interesting video](https://www.youtube.com/watch?v=cqjpa8-Cp-s) about some macOS utilities. I love small utilities, but I like it even better, when a problem can be solved with system functions. That is the case here. He mentions Helium - an app to use a form of picture in picture mode for websites that don't support the native PIP.
However, there is a better solution! And this solution works on Mac as well as iPad!
<!-- more -->
You can use a small [bookmarklet](https://en.wikipedia.org/wiki/Bookmarklet) that pushes the current HTML5 video on screen into the native PIP. And yes, it also works with Netflix, **if** you are on macOS Mojave or up (as far as I can tell, Netflix doesn't run in the previous versions of Safari).
Create a new bookmark, enter the following string as the address, give it a nice emoji (like this: ⤵️), voilà! You can now use the native PIP for nearly all your videos!
Here is the code:
```
javascript:document.querySelector(%22video%22).webkitSetPresentationMode(%22picture-in-picture%22);
```
@@ -0,0 +1,71 @@
---
layout: post
title: "How to Begin an English Sentence"
categories:
- Tutorials
tags:
- English
- Writing
last_modified_at:
excerpt_separator: <!-- more -->
---
During the writing of my thesis, I collected some English words you can use two empower your writing style.
<!-- more -->
Addition:
also, again, as well as, besides, coupled with, furthermore, in addition, likewise, moreover, similarly
Consequence:
accordingly, as a result, consequently, for this reason, for this purpose,
hence, otherwise, so then, subsequently, therefore, thus, thereupon, wherefore
Generalizing:
as a rule, as usual, for the most part,
generally, generally speaking, ordinarily, usually
Exemplifying:
chiefly, especially, for instance, in particular, markedly, namely,
particularly, including, specifically, such as
Illustration:
for example, for instance, for one thing, as an illustration,
illustrated with, as an example, in this case
Emphasis
above all, chiefly, with attention to, especially, particularly, singularly
Similarity:
comparatively, coupled with, correspondingly, identically, likewise, similar, moreover, together with
Exception:
aside from, barring, besides, except, excepting, excluding, exclusive of, other than, outside of, save
Restatement:
in essence, in other words, namely, that is, that is to say,
in short, in brief, to put it differently
Contrast and Comparison:
contrast, by the same token, conversely, instead, likewise,
on one hand, on the other hand, on the contrary, rather,
similarly, yet, but, however, still, nevertheless, in contrast
Sequence:
at first, first of all, to begin with, in the first place, at the same time,
for now, for the time being, the next step, in time, in turn, later on,
meanwhile, next, then, soon, the meantime, later, while, earlier,
simultaneously, afterward, in conclusion, with this in mind,
Summarizing:
after all, all in all, all things considered, briefly, by and large, in any case, in any event,
in brief, in conclusion, on the whole, in short, in summary, in the final analysis,
in the long run, on balance, to sum up, to summarize, finally
Diversion:
by the way, incidentally
Direction:
here, there, over there, beyond, nearly, opposite, under, above,
to the left, to the right, in the distance
@@ -0,0 +1,52 @@
---
layout: post
title: "Blackhole"
categories:
- Art
tags:
- English
- Reading
last_modified_at:
excerpt_separator: <!-- more -->
---
This is a text I found on the internet and saved it. If anybody knows the source, please tell me, so I can give credit.
<!-- more -->
# Blackhole
Imagine, just for a moment, that you are aboard a spaceship equipped with a magical engine capable of accelerating you to any arbitrarily high velocity. This is absolutely and utterly impossible, but it turns out it'll be okay, for reasons you'll see in a second.
Because you know your engine can push you faster than the speed of light, you have no fear of black holes. In the interest of scientific curiosity, you allow yourself to fall through the event horizon of one. And not just any black hole, but rather a carefully chosen one, one sufficiently massive that its event horizon lies quite far from its center. This is so you'll have plenty of time between crossing the event horizon and approaching the region of insane gravitational gradient near the center to make your observations and escape again.
As you fall toward the black hole, you notice some things which strike you as highly unusual, but because you know your general relativity they do not shock or frighten you. First, the stars behind you — that is, in the direction that points away from the black hole — grow much brighter. The light from those stars, falling in toward the black hole, is being blue-shifted by the gravitation; light that was formerly too dim to see, in the deep infrared, is boosted to the point of visibility.
Simultaneously, the black patch of sky that is the event horizon seems to *grow* strangely. You know from basic geometry that, at this distance, the black hole should subtend about a half a degree of your view — it should, in other words, be about the same size as the full moon as seen from the surface of the Earth. Except it isn't. In fact, it fills half your view. Half of the sky, from notional horizon to notional horizon, is pure, empty blackness. And *all* the other stars, nearly the whole sky full of stars, are crowded into the hemisphere that lies behind you.
As you continue to fall, the event horizon opens up beneath you, so you feel as if you're descending into a featureless black bowl. Meanwhile, the stars become more and more crowded into a circular region of sky centered on the point immediately aft. The event horizon does not *obscure* the stars; you can watch a star just at the edge of the event horizon for as long as you like and you'll never see it slip behind the black hole. Rather, the field of view through which you see the rest of the universe gets smaller and smaller, as if you're experiencing tunnel-vision.
Finally, just before you're about to cross the event horizon, you see the entire rest of the observable universe contract to a single, brilliant point immediately behind you. If you train your telescope on that point, you'll see not only the light from all the stars and galaxies, but also a curious dim red glow. This is the cosmic microwave background, boosted to visibility by the intense gravitation of the black hole.
And then the point goes out. All at once, as if God turned off the switch.
You have crossed the event horizon of the black hole.
Focusing on the task at hand, knowing that you have limited time before you must fire up your magical spaceship engine and escape the black hole, you turn to your observations. Except you don't see anything. No light is falling on any of your telescopes. The view out your windows is blacker than mere black; you are looking at non-existence. There is *nothing* to see, *nothing* to observe.
You know that somewhere ahead of you lies the singularity … or at least, whatever the universe deems fit to exist at the point where our mathematics fails. But you have no way of observing it. Your mission is a failure.
Disappointed, you decide to end your adventure. You attempt to turn your ship around, such that your magical engine is pointing toward the singularity and so you can thrust yourself away at whatever arbitrarily high velocity is necessary to escape the black hole's hellish gravitation. But you are thwarted.
Your spaceship has sensitive instruments that are designed to detect the gradient of gravitation, so you can orient yourself. These instruments should point straight toward the singularity, allowing you to point your ship in the right direction to escape. Except the instruments are going haywire. They seem to indicate that the singularity lies *all around you.* In *every* direction, the gradient of gravitation increases. If you are to believe your instruments, you are at the point of lowest gravitation inside the event horizon, and every direction points "downhill" toward the center of the black hole. So *any direction you thrust your spaceship* will push you closer to the singularity and your death.
This is clearly nonsense. You cannot believe what your instruments are telling you. It must be a malfunction.
But it isn't. It's the absolute, literal truth. Inside the event horizon of a black hole, there *is* no way out. There are no directions of space that point away from the singularity. Due to the Lovecraftian curvature of spacetime within the event horizon, all the trajectories that *would* carry you away from the black hole now point into the past.
In fact, this is the definition of the event horizon. It's the boundary separating points in space where there *are* trajectories that point away from the black hole from points in space where there are none.
Your magical infinitely-accelerating engine is of no use to you … because you cannot find a direction in which to point it. The singularity is all around you, in every direction you look.
And it is getting closer.
@@ -0,0 +1,26 @@
---
layout: post
title: "Die Rechnung"
tags:
- Deutsch
- Checklist
last_modified_at: 2019-03-25
excerpt_separator: <!-- more -->
---
Die Rechnung ist eines der wesentlichsten Dokumente des Geschäftsverkehrs. Da sie ein formales Dokument ist, müssen einige Regeln eingehalten werden, damit eine Rechnung _gültig_ ist und der Kunde bezahlen muss. Der Gesetzgeber hat eindeutig festgelegt, welche Angaben enthalten sein müssen ([§ 14 UStG](https://www.gesetze-im-internet.de/ustg_1980/__14.html)):
<!-- more -->
- Der vollständige Name und die Anschrift des Rechnungs**steller**
- Der vollständige Name und die Anschrift des Rechnungs**empfänger**
- Die Steuernummer des Rechnungs**stellers**
- Das Ausstellungsdatum
- Eine eindeutig Rechnungsnummer
- Die Menge und Art der gelieferten Leistung
- Das Datum der Lieferung (auch wenn identisch mit oben!)
- Der Netto-Betrag der Lieferung
- Den anzuwendenden Steuersatz
- Den anfallenden Steuerbetrag
@@ -0,0 +1,29 @@
---
layout: post
title: "iPad Gestures"
categories:
- Tips
tags:
- English
- Apple
last_modified_at:
excerpt_separator: <!-- more -->
---
I did it! I bought an iPad and an Apple Pencil for christmas last year. I write a lot for my university classes and I didn't like that I often had to cross out things on paper (because I wrote something down wrong) and had to write them again. I was not sure, if an iPad is the right device for me -- but turns out it is. It is awesome. If you make a mistake, you erase it and write it again. Wrong sequence of your sentences? Just move them around. The notes come out awesome.
Additionally I learned a few gestures that are really useful:
<!-- more -->
- Swipe with two fingers on the virtual keyboard to move cursor.
- Tap and hold with two fingers to begin selecting, then move fingers to expand selection, OR
- Tap once with two fingers to select single word.
- Double tap with two fingers to select sentence.
- Triple tap with two fingers to select paragraph.
While text is selected:
- Swipe left/up with two fingers to move left selection handle.
- Swipe right/down with two fingers to move right selection handle.
- Tap once with two fingers to exit selection and return to cursor mode.
@@ -0,0 +1,81 @@
---
layout: post
title: "Use the Pumping Lemma for Regular Languages"
categories:
- Tutorials
tags:
- Proof
- Computer Science
last_modified_at: 2019-04-04
excerpt_separator: <!-- more -->
---
This semester I finished my course about automata and languages. I learned a lot and it was really enjoyable. From this field, there was [a question about the Pumping Lemma on the computer science subreddit](https://old.reddit.com/r/computerscience/comments/atrs4y/pumping_lemma_in_theory_of_computation/). So naturally, if someone ask about a thing I know about, I'll try to explain it as best as I can -- repetition is key for retaining knowledge!
<!-- more -->
# My Explanation
[My original post on Reddit.](https://old.reddit.com/r/computerscience/comments/atrs4y/pumping_lemma_in_theory_of_computation/eh3aw9k/)
To understand the PL, we think about it in two steps. I'll do it for the regular languages. You can do the same on your own for the context free languages. The idea is the same.
1. We create a visual model to understand what it is about.
2. We do a PL proof.
## 1. Creating a visual model in your mind.
Firstly, we have to keep in mind that we want to show that a language is not regular. Let's reason a little bit more about regular languages:
- Regular languages can be accepted by finite automata (FA). That means: if your language is regular, there is an FA that accepts this language.
- To check, whether a word is accepted by an FA, you start in a state, start reading in letters of your word and follow the edges through the FA. If the whole word is read and we end up in a final state, the FA accepts the word.
- But hold on a second! FA can also accept words that have more letters than we have states and edges. How can that be?! The answer: loops.
- Now, given any regular language, we **know** that there is an FA that accepts it (this is a theorem).
- That means: if we have a word, that has more letters than we have states, but is still accepted by our FA, we **have to have** a loop in our FA.
- Think about it: we can repeat this loop as many times as we want and the FA would still accept words that are processed by going through the loop repeatedly. **It has to!**
- This repeating of the loop is referred to as pumping a word up or down.
## 2. Doing a proof.
Now, secondly, you want to proof something using this lemma. Let's start with the PL (really try to understand this line!):
`L ∈ REG → ∃n ∈ ∀x ∈ L: |x| ≥ n ∃u, v, w: x = u ∘ v ∘ w, |v| ≥ 1, |uv| ≤ n ∀i ∈ : u ∘ vⁱ ∘ w ∈ L`
I'll break it down. Remember: This is a theorem. If you meet the conditions of the implication (part on the left), you now **know** that the part on the right is true.
1. `L ∈ REG →`: "Given a regular language, the following is true."
2. `∃n ∈ `: "There is a natural number"
3. `∀x ∈ L: |x| ≥ n`: "For every word `x` that is in the language and longer than this natural number"
- Remember the argument with the loops from part 1. This just says: we now have a word that has more letters than we have states.
4. `∃u, v, w: x = u ∘ v ∘ w, |v| ≥ 1, |uv| ≤ n`: "You can split up the word `x` into three parts: `u, v, w` where the length of `v` is equal to or bigger than `1` and the length of `u ∘ v` is smaller than our natural number from before"
- Here we describe the loop in more detail. `v` is the part that we can pump, because there is a loop that processes v (and can thus process arbitrary iterations of v - or skip it altogether. And because `u ∘ v` is smaller than `n`, we didn't need a loop until now. We only really **need** a loop, if our word has more letters than we have states!
5. `∀i ∈ : u ∘ vⁱ ∘ w ∈ L`: "If all the conditions before have been met, we can now pump `v` up or down and the resulting word is still in the language!"
- Since it is a loop, pumping doesn't make a difference. If you go the loop a million times, the word is still in the language.
That's it. Again, because it is proved, you **know** it's true if all the conditions are met.
We want to use the lemma to show, that a language **is not** a regular language. Let's have a look at the implication from above. Think about the left part of the implication (`L ∈ REG`) as `A` and the right part (`∃n ∈ ∀x ∈ L: |x| ≥ n ∃u, v, w: x = u ∘ v ∘ w, |v| ≥ 1, |uv| ≤ n ∀i ∈ : u ∘ vⁱ ∘ w ∈ L`) as `B`: `A → B`.
We can now do the following transformation:
`A → B ≡ ¬B → ¬A`
To pull in the negation on the right side of this transformation, all the quantifiers have to "flip around". This means the sentence now looks like this:
`∀n ∈ ∃x ∈ L: |x| ≥ n ∀u, v, w: x = u ∘ v ∘ w, |v| ≥ 1, |uv| ≤ n ∃i ∈ : u ∘ vⁱ ∘ w ∉ L → L ∉ REG`
Again, this is still the Pumping Lemma. We didn't change it, we just used an transformation for the implication that is equivalent. If you meet the conditions on the left, you **know** the sentence on the right is true.
Let's use this on an example: Show that `L = {aᵏ ∘ bᵏ | k ≥ 0}` is not regular.
1. Take any number `n`.
2. Select a word with the requirement `x ∈ L` with `|x| ≥ n`. Your mathematical creativity is requested here! You need to pick a word that helps you show the rest of the conditions easily! We are going to pick: `x = aⁿbⁿ`. This is convenient, because its obvious that it is as least as long as n (n occurs twice in it as an exponent). The important property to note: there are exactly as many `a` as there are `b` in this word. So if we can pump it in a way, that this is not the case anymore, we are golden!
3. Now we have to look at **all** of the partitions `x = uvw` with the conditions `|v| ≥ 1` and `|uv| ≤ n`. Since we have to look at all of them we just say: Let's assume these conditions are met (we can now use them in the next step).
4. Pick an `i` that shows that `u ∘ vⁱ ∘ w ∉ L`. Let's take `i = 0`.
- Since our word is `aⁿbⁿ` and one of the conditions is `|uv| ≤ n`, we know that `uv` can **only** consist of the letter `a`.
- And because we have the condition `|v| ≥ 1`, we also know that `v` has to contain **at least** one letter `a`.
- If we now remove this letter (or maybe its more than one letter, it doesn't matter), the amount of letters `a` in the word `x` is now not equal to the amount of letters `b` in the word.
- Hence: Our word is not part of the language any more (`u ∘ v⁰ ∘ w ∉ L`), violating the PL.
This shows that `L = {aᵏ ∘ bᵏ | k ≥ 0}` is not a regular language.
@@ -0,0 +1,25 @@
---
layout: post
title: "Collection of High Quality Swift Libraries"
categories:
- Programming
tags:
- English
- Swift
last_modified_at: 2019-03-30
excerpt_separator: <!-- more -->
---
Libraries are an important part of programming. However, there should be a **really** good reason, if you decide to use a library. And if you use one, it should be a good one. These are some from my collection:
<!-- more -->
- [JTAppleCalendar](https://github.com/patchthecode/JTAppleCalendar): Need a calendar view? Don't roll your own.
- [Keychain](https://github.com/evgenyneu/keychain-swift): Have something that need secure storage, like a password? Put it in the keychain.
- [SPPermission](https://github.com/IvanVorobei/SPPermission): Your app needs permissions? Inform the user properly. It's important.
- [SwiftDate](https://github.com/malcommac/SwiftDate): Handles all your date and time needs. [Don't roll your own](https://www.youtube.com/watch?v=-5wpm-gesOY).
- [WhatsNewKit](https://github.com/SvenTiigi/WhatsNewKit): Welcome your new user like apple does.
## Helper
- [SwiftyUserDefaults](https://github.com/radex/SwiftyUserDefaults): A small wrapper around NSUserDefaults that makes the usage swifter.
@@ -0,0 +1,144 @@
---
layout: post
title: "Install Mailtrain on Uberspace 7"
categories:
- Tutorials
tags:
- English
- Self-Hosted Software
last_modified_at: 2020-07-21
excerpt_separator: <!-- more -->
---
This tutorial explains how to install [Mailtrain](https://mailtrain.org) on a [Uberspace 7](uberspace.de). [Mailtrain](https://mailtrain.org/) is a self-hosted open-source (released under the [GPL
v3.0](https://github.com/Mailtrain-org/mailtrain/blob/master/LICENSE).) newsletter app built on top of [Nodemailer](https://nodemailer.com/). I am following the [manual installation guide](https://github.com/Mailtrain-org/mailtrain#quick-start---manual-install-any-os-that-supports-nodejs) from the official Mailtrain repo and add some additional Uberspace infos. I contributed [this guide](https://lab.uberspace.de/guide_mailtrain.html) to the [Uberlab](https://lab.uberspace.de/) and earned my first [Ubercup](https://github.com/Uberspace/lab/blob/master/CONTRIBUTING.md#reward).
<!-- more -->
## Installation
This guide uses Node.js version 12, which is the [default](https://manual.uberspace.de/lang-nodejs.html#standard-version) on Uberspace 7 at at the moment.
Clone the [GitHub](https://github.com/Mailtrain-org/mailtrain)
repository:
```console
[isabell@stardust ~]$ git clone git://github.com/Mailtrain-org/mailtrain.git
[isabell@stardust ~]$
```
Install the required dependencies:
```console
[isabell@stardust ~]$ cd mailtrain
[isabell@stardust mailtrain]$ npm install --production
[isabell@stardust mailtrain]$
```
## Configuration
### Database Setup
Create a new database:
```console
[isabell@stardust mailtrain]$ mysql -e "CREATE DATABASE ${USER}_mailtrain;"
[isabell@stardust mailtrain]$
```
### Mailtrain Config
Copy the example config file:
```console
[isabell@stardust mailtrain]$ cp config/default.toml config/production.toml
[isabell@stardust mailtrain]$
```
Update `production.toml` with your MySQL settings; look for the
`[mysql]` block:
```console
...
[mysql]
host="localhost"
user="isabell"
password="MySuperSecretPassword"
database="isabell_mailtrain"
...
```
### Web Backend Config
[Mailtrain](https://mailtrain.org/) is running on port 3000. Configure the server to respond to port 3000 using web backends:
``` console
[isabell@stardust ~]$ uberspace web backend set / --http --port 3000
[isabell@stardust ~]$
```
### Supervisord Daemon Setup
Create `~/etc/services.d/mailtrain.ini` with the following content:
```ini
[program:mailtrain]
directory=%(ENV_HOME)s/mailtrain/
command=env NODE_ENV=production /bin/node index.js
autostart=yes
autorestart=yes
```
If it's not in state RUNNING, check your configuration.
### Login and Change Admin Credentials
{% include bootstrap/alert.html
content="Change the default admin credentials to prevent unauthorized access of your data!"
style="danger"
%}
Your [Mailtrain](https://mailtrain.org/) installation should now be
reachable on `https://isabell.uber.space`. Log in with the username
`admin` and the password `test`.
Go to `https://isabell.uber.space/users/account` and change your email
address as well as your password.
{% include bootstrap/alert.html
content="It is not possible to change the username in the GUI. If you want to change the default username `admin` to something else or add additional users, you have to do it directly in the database."
style="info"
%}
## Finishing installation
Go to `https://isabell.uber.space/settings`. In the **General Settings** section change the **Service Address (URL)**
to `https://isabell.uber.space/`.
In the **Mailer Settings** section change the
> - *Hostname*,
> - *Port*,
> - *Encryption*,
> - *username*,
> - *password*, and
> - test your settings by pressing the Button **Check Mailer Config**.
{% include bootstrap/alert.html
content="Uberspace does not allow mass mailings from their servers according to their House Rules. However, you can use Mailtrain as the admin interface for your mailing needs. Use the SMTP services from AWS SES, Sendgrid, Mailgun, etc. for the actual mailing."
style="warning"
%}
## Best Practices
* Test the configuration by creating a new list and subscribing yourself
to it.
* Craft your campaign with love and dedication.
* Dont spam users that dont want your newsletter.
------------------------------------------------------------------------
Tested on Uberspace v7.7.0 with NodeJS v12 and MariaDB 10.3.23.
@@ -0,0 +1,45 @@
---
layout: post
title: "The Collection"
categories:
- Tips
tags:
- English
- Collection
last_modified_at: 2020-08-28
excerpt_separator: <!-- more -->
---
During my time on the Internet, I encountered many things. This post is a collection of the cool things. I will probably update it once in a while. Since I am living in Germany, some of the tips may not be useful for everyone. In order of coolness.
<!-- more -->
## Web Services
[Uberspace](https://uberspace.de) is a hosting provider. They offer a shared hosting experience that is a little bit more limited than a root server. However, their support is amazing and it's a super good place to host for tinkerers and small projects. Highly recommended. Check out my [Tutorials](/category/tutorials.html) or the [Uberlab for U7](https://lab.uberspace.de) for things you can do on your Uberspace!
Things I am using on Uberspace:
- [InvoicePlane](http://invoiceplane.com): Simple invoicing software. Offers sending offers and invoices via email, too!
- [Matomao](https://matomo.org): Analytics software to avoid Google.
- [Redmine](http://redmine.org): Amazing project management solution.
- [Syncthing](http://syncthing.net): File synchronisation alternative.
[Tecspace](https://tecspace.de) is a hosting provider and domain registrar. I buy and manage my domains through their service. It is extremely cheap, costing only 2,50 EUR per year, if you have 10 or more domains. I love their admin interface. It is simple, behaves like a website should behave (no JavaScript shenanigans) and is very powerful.
[Pinboard](https://pinboard.in) is a bookmarking service. It's minimalistic, easy to use and offers an archiving service so you will never lose these good articles on the internet again.
## Software
### Pictures, Design, Illustrating
[Affinity](https://affinity.serif.com/) produces [Affinity Designer](https://affinity.serif.com/en-gb/designer/) and [Affinity Photo](https://affinity.serif.com/en-gb/photo/). They are competitors to the popular Adobe Photoshop and Illustrator. These two programs are *exceptional*. You can do basically everything you can do with their Adobe counterparts, but they only cost 55 EUR each. No subscriptions, no recurring fees. The interface is polished and if you are an Adobe user you will be right at home. Quit Adobe today. Don't let them milk you.
[Appollo One](https://www.apollooneapp.com/) is a really fast image viewer.
### Random Apps
[Sensei](https://sensei.app/) is a system monitoring app with a nice Mac compliant interface.
[Mactracker](http://mactracker.ca/) is an app that lists all apple hardware and their specifications. No need to google for these things anymore.
@@ -0,0 +1,29 @@
---
layout: post
title: "Strategies from the Happiness Lab"
categories:
- Summaries
tags:
- English
- Philosophy
last_modified_at:
excerpt_separator: <!-- more -->
---
I love listening to podcasts while I am out running. The latest one I found is [The Happiness Lab](https://www.happinesslab.fm/) from and with Dr. Laurie Santos, a professor teaching at Yale. She looks at happiness scientifically and takes an active approach: [You have it in your own hands to improve your happiness](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000449594792). The podcast discusses various strategies with various scientists and experts from their respective field.
This is a collection of these strategies you can employ; with the link to the corresponding episode for more information.
<!-- more -->
* [Meditate.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000469606673) You have probably heard about people recommending meditating a thousand times. Do it. Start with 1 minute every day. The research of the benefits seems to be overwhelming.
* [Sleep enough.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000463759567) Trivial. Humans need sleep. Get. Some. Make it a ritual to go to bed. Make the bed a sanctuary. No screens, no distractions. If you are lying in bed, you sleep. If you can't sleep, leave the bed and try again later. You can combine the ritual with meditation (see above).
* [Remove choice.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000455959891) Being in control of and having to decide everything is exhausting. Remove unnecessary choices from your life. Have a big wardrobe? Reduce it and go minimal. Or to quote President Obama who always wore a white shirt and cycled through his suits: "Do you know how many decision I have to make throughout the day? You think I also want to decide what to wear?"
* [Coach yourself from the third person.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000468907282) The research suggests that you perform better and are happier, if you think about the challenges you are facing from a third person perspective. The key term is **distancing**. Distance yourself to get a clearer picture of what is going on. You can use personal distancing (use your name instead of "I"): "Felix knows what he is doing and has experience. Trust him." You can use temporal distancing: "Felix has faced this threat before and came out successful." You can use group distancing: "We are a strong society and can solve this challenge together."
* [Connect with others. Even strangers.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000452731206) Modern life aims at removing all inconveniences. But it also removes social connections with other people. The example from the podcast is from the guy that invented the ATM. When there were still bank tellers, you had to wait in line -- where you might have to interact socially -- and had to interact with the teller. A person. Research suggests that happiness improves just by interacting with other people
* [Frame your emotions.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000469255597) When encountering an emotion, you have 5 seconds to decide how to react to it. Use different frames depending on the situation. Examples for these frames:
* **The comedic frame** Try to tell a joke about the situation.
* **The future storytelling frame** Live your life in a way so that your story, told **truthfully**, makes you look like the person you strife to be. Which story sounds better to you? The story about a miserable and frustrated person that gave up on the slightest problem **or** the story about the person that strongly and cleverly encounters the challenges life throws at her and masters these challenges while smiling.
* **The stoic gods challenge frame** Use stoic, imaginary gods as a psychological device: Every setback you face in life is a test these gods have designed to test you and your character. And you want and can prove to them that you are up to the challenge. The harder the challenge is, the more trust the gods have in you.
* [Practice negative visualization.](https://podcasts.apple.com/de/podcast/the-happiness-lab-with-dr-laurie-santos/id1474245040?l=en&i=1000469255597) Pause every once in a while during the day and think about what you could lose and how that would make you feel. Don't dwell on these thoughts. Just let them flicker for a second. This aims at increasing your appreciation for the people and things you have in your life.
@@ -0,0 +1,85 @@
---
layout: post
title: "Ideas"
categories:
- Personal
tags:
- English
- Collection
last_modified_at:
excerpt_separator: <!-- more -->
---
Many people have ideas. Ideas are not special. What makes and breaks an idea is its realization and/or implementation. Here are some of **my** product ideas. Implement them, if you like them! Then send me an [email](mailto:felixfoertsch@gmail.com) to show them to me, please. 😁
<!-- more -->
## Product Ideas
**Flatpen:** Pens have a problem. They are round and stiff and that makes them harder to carry around. The idea: Create a pen that uses regular pen mines, but folds flat so it can be put inside of a notebook without making it wobble.
**Process Visualization with Z-Layers:** Processes are an important part of business development and optimization. Their visualization is important for communicating them. Most process visualization software is clunky to use. Finding the right layer of abstractions with processes is hard by default -- software should make it easier. This has to be a combined solution: From the editor to the reader. The core idea is using Z-layer zooming to make it more intuitive (e.g. pinching in mobile and tablet apps).
**Magic Handshake:** Create a system that supports favors. Being in the system opens you doors, because you know someone. Like an exclusive club.
**10 Minute Mentor:** Finding is a mentor is difficult. Make it easier.
**Sane Games:** Create a list of games that are *sane*: no IAP, no psycho abuse, etc.
## Web App Ideas
**Sign-up:** Create an event where people can sign up really easily. Like [Raid Helper](https://raid-helper.com/), but generalized.
**WOOP:** PWA that implements the [GROW](https://en.wikipedia.org/wiki/GROW_model) or [WOOP](https://en.wikipedia.org/wiki/Gabriele_Oettingen) mental model.
**Predefined Workflow Builder/Checklister/Show the Way:** Many task in modern life follow step-by-step processes. It is **really** inefficient that everybody has to learn them individually. It should be easy to download a pre-created checklist for a specific task and then succeed with just following this checklist. E.g. "How to do a product launch" --> Step 1: Do X. Step 2: Do Y., "How to learn JavaFX" --> etc. Specialised Version of this could be a "You should app". A collection of things everybody should do and/or have. Have a bank account, have insurance, etc.
**GitHub Contributions for Everything:** GitHub Contributions are awesome. They give a quick and intuitive overview about progress. Create a way that allows tracking everything like this.
**Applicant Oriented Applications:** Applications are awful for the applicant. They are at the mercy of organizations. They have to send in all their information and then they have to wait. And they have to do that multiple times. Use different interfaces, create different formats, and so on. It should be easier.
**Make it very easy to donate to a good cause/org:** One click donations. It is not easy to set up donations in Germany. There is a lot of hassle involved with creating receipts etc. This should be super easy for the associated organizations and should allow integrated systems like PayPal and Stripe for payments.
**Local Twitter:** It's not always easy to know what's happening around your. Make an app that makes it really easy to know what public events are happening right now around you. Concert? Demonstration? Check and know.
**Gamekey Exchange:**
Enable people that buy things like humble bundle to trade their unused keys with each other.
## Computer and Phone App Ideas
**On time:** Calendar integration that allows one click information to others, if you are on time or not.
**Hierarchical Documentation:** Documentation of software is often flat, even though hierarchies are at the core of many projects. Tools should display hierarchies to make it easier to quickly grasp software libraries.
**Moderator Toolbox:** Organizing groups is hard. Make using speech lists, protocols, etc. easy to do.
**Cadence and Heartbeat Music:** Generate electronic music (e.g. with AI) and use the heartbeat sensor of the Apple Watch attach it to the cadence and/or heart rate of the person.
**Vaccination Card:** There is a yellow book that helps track vaccinations. Make one that's on your phone.
**Walk the City:** Exploring a city is awesome. Make an app that tracks all routes/streets you have already been to on the map to facilitate walking every road once.
**Checkpoints:** Create a system that allows people with bad time management to tell an accurate prediction on when they'll get somewhere. Use map data and checkpoints to find out the time.
**Color Clipboard:** Monitor clipboard and store Hex codes. Give a nice UI to create palettes, etc.
**Kontakte:** Create a Tinder-like interface to clean-up contacts: Keep, delete, edit. Have a nice and easy way to add notes and tags. Potentially: Add whitelist/blocklist.
**Business Plan Archive:** Like ideas business plans have way less value than people think. Put them in the public domain.
**Track a Thing:** App that has a unified interface to track things **very** easily. Did a run: Track. How many days since you last called your mother: Track. Is your Doner bigger or smaller than average: Track.
**Single Player Raider (Game):** A game where you do a 40-person raid, but you do it solo on your own terms.
## Apps that already exist (or probably exists), but require better design, should not cost money or should be open source
- **Tiddlywiki for Mac**
- **Anki for Mac**
- **Twitch for Mac:** mpv/IINA as player and chat on the bottom (native portrait mode)
- **Ebook reader for Mac:** Books always adds the PDF/ePub to the library, which is not always required
- **Reddit but with a limit:** Scrolling is unhealthy.
- **Archiver for Mac:** Easy archiving of things. YouTube via youtube-dl, etc.
- https://www.progressbarosx.com/
- **Ambience:** Menu bar one-click music player for study/background music
@@ -0,0 +1,163 @@
---
layout: post
title: "Apple Colors in SCSS"
categories:
- Design
tags:
- English
last_modified_at:
excerpt_separator: <!-- more -->
---
Colors have a big impact on how software looks. Personally, I think macOS and iOS are beautiful and the colors are very well selected. Since I am not a designer, but I want to understand **why** these systems always looks so good, I started designing this website using the Apple colors. The first step I took was creating variables for the Apple colors from the [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/) ([iOS](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/)/[macOS](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/color/)).
I published them on GitHub as gists so you can use them, too. It's just the raw variables; but I could not find them anywhere else in this SCSS form. Gist [macOS-colors-dark.scss](https://gist.github.com/felixfoertsch/52904ab569521158dd8494024c0a5d77), [macOS-colors-light.scss](https://gist.github.com/felixfoertsch/36922ee9a74d9bd0c0887f62cecb7041), [iOS-colors-dark.scss](https://gist.github.com/felixfoertsch/69dd59c9e541788056ee6c70928c3769), [iOS-colors-light.scss](https://gist.github.com/felixfoertsch/e4c73a673bd769218c39c17ac09127aa).
Read more for the actual variables.
<!-- more -->
```scss
// macOS-colors-dark.scss
$macOS-systemBlue-dark: rgba(10, 132, 255, 1);
$macOS-systemBrown-dark: rgba(172, 142, 104, 1);
$macOS-systemGray-dark: rgba(152, 152, 157, 1);
$macOS-systemGreen-dark: rgba(50, 215, 75, 1);
$macOS-systemIndigo-dark: rgba(94, 92, 230, 1);
$macOS-systemOrange-dark: rgba(255, 159, 10, 1);
$macOS-systemPink-dark: rgba(255, 55, 95, 1);
$macOS-systemPurple-dark: rgba(191, 90, 242, 1);
$macOS-systemRed-dark: rgba(255, 69, 58, 1);
$macOS-systemTeal-dark: rgba(100, 210, 255, 1);
$macOS-systemYellow-dark: rgba(255, 214, 10, 1);
$macOS-alternateSelectedControl-dark: rgba(0, 88, 208, 1);
$macOS-alternateSelectedControlText-dark: rgba(255, 255, 255, 1);
$macOS-controlBackground-dark: rgba(30, 30, 30, 1);
$macOS-controlText-dark: rgba(255, 255, 255, 0.8);
$macOS-disabledControlText-dark: rgba(255, 255, 255, 0.2);
$macOS-grid-dark: rgba(255, 255, 255, 0.1);
$macOS-headerText-dark: rgba(255, 255, 255, 1);
$macOS-highlight-dark: rgba(180, 180, 180, 1);
$macOS-labelColor-dark: rgba(255, 255, 255, 0.8);
$macOS-linkColor-dark: rgba(65, 156, 255, 1);
$macOS-placeholderTextColor-dark: rgba(255, 255, 255, 0.2);
$macOS-quaternaryLabelColor-dark: rgba(255, 255, 255, 0.1);
$macOS-secondaryLabelColor-dark: rgba(255, 255, 255, 0.5);
$macOS-selectedContentBackgroundColor-dark: rgba(0, 88, 208, 1);
$macOS-selectedControlColor-dark: rgba(63, 99, 109, 1);
$macOS-selectedControlTextColor-dark: rgba(255, 255, 255, 0.8);
$macOS-selectedMenuItemTextColor-dark: rgba(255, 255, 255, 1);
$macOS-selectedTextBackgroundColor-dark: rgba(63, 99, 139, 1);
$macOS-selectedTextColor-dark: rgba(255, 255, 255, 1);
$macOS-separatorColor-dark: rgba(255, 255, 255, 0.1);
$macOS-shadowColor-dark: rgba(0, 0, 0, 0);
$macOS-tertiaryLabelColor-dark: rgba(255, 255, 255, 0.2);
$macOS-textBackgroundColor-dark: rgba(30, 30, 30, 1);
$macOS-textColor-dark: rgba(255, 255, 255, 1);
$macOS-underPageBackgroundColor-dark: rgba(40, 40, 40, 1);
$macOS-unemphasizedSelectedContentBackgroundColor-dark: rgba(70, 70, 70, 1);
$macOS-unemphasizedSelectedTextBackgroundColor-dark: rgba(70, 70, 70, 1);
$macOS-unemphasizedSelectedTextColor-dark: rgba(255, 255, 255, 1);
$macOS-windowBackgroundColor-dark: rgba(50, 50, 50, 1);
$macOS-windowFrameTextColor-dark: rgba(255, 255, 255, 0.8);
```
```scss
// macOS-colors-light.scss
$macOS-systemBlue: rgba(0, 122, 255, 1);
$macOS-systemBrown: rgba(162, 132, 94, 1);
$macOS-systemGray: rgba(142, 142, 147, 1);
$macOS-systemGreen: rgba(40, 205, 65, 1);
$macOS-systemIndigo: rgba(88, 86, 214, 1);
$macOS-systemOrange: rgba(255, 149, 0, 1);
$macOS-systemPink: rgba(255, 45, 85, 1);
$macOS-systemPurple: rgba(175, 82, 222, 1);
$macOS-systemRed: rgba(255, 59, 48, 1);
$macOS-systemTeal: rgba(90, 200, 250, 1);
$macOS-systemYellow: rgba(255, 204, 0, 1);
$macOS-alternateSelectedControl: rgba(0, 99, 255, 1);
$macOS-alternateSelectedControlText: rgba(255, 255, 255, 1);
$macOS-controlBackground: rgba(255, 255, 255, 1);
$macOS-controlText: rgba(0, 0, 0, 0.8);
$macOS-disabledControlText: rgba(0, 0, 0, 0.2);
$macOS-grid: rgba(204, 204, 204, 1);
$macOS-headerText: rgba(0, 0, 0, 0.8);
$macOS-highlight: rgba(255, 255, 255, 1);
$macOS-labelColor: rgba(0, 0, 0, 0.8);
$macOS-linkColor: rgba(0, 104, 218, 1);
$macOS-placeholderTextColor: rgba(0, 0, 0, 0.2);
$macOS-quaternaryLabelColor: rgba(0, 0, 0, 0.1);
$macOS-secondaryLabelColor: rgba(0, 0 ,0, 0.5);
$macOS-selectedContentBackgroundColor: rgba(0, 99, 225, 1);
$macOS-selectedControlColor: rgba(179, 215, 255, 1);
$macOS-selectedControlTextColor: rgba(0, 0, 0, 0.8);
$macOS-selectedMenuItemTextColor: rgba(255, 255, 255, 1);
$macOS-selectedTextBackgroundColor: rgba(179, 215, 255, 1);
$macOS-selectedTextColor: rgba(0, 0, 0, 1);
$macOS-separatorColor: rgba(0, 0, 0, 0.1);
$macOS-shadowColor: rgba(0, 0, 0, 1);
$macOS-tertiaryLabelColor: rgba(0, 0, 0, 0.2);
$macOS-textBackgroundColor: rgba(255, 255, 255, 1);
$macOS-textColor: rgba(0, 0, 0, 1);
$macOS-underPageBackgroundColor: rgba(150, 150, 150, 0.9);
$macOS-unemphasizedSelectedContentBackgroundColor: rgba(220, 220, 220, 1);
$macOS-unemphasizedSelectedTextBackgroundColor: rgba(220, 220, 220, 1);
$macOS-unemphasizedSelectedTextColor: rgba(0, 0, 0, 1);
$macOS-windowBackgroundColor: rgba(236, 236, 236, 1);
$macOS-windowFrameTextColor: rgba(0, 0, 0, 0.8);
```
```scss
// iOS-colors-dark.scss
$iOS-systemBlue-dark: rgba(10, 132, 255, 1);
$iOS-systemGreen-dark: rgba(48, 209, 88, 1);
$iOS-systemIndigo-dark: rgba(94, 92, 230, 1);
$iOS-systemOrange-dark: rgba(255, 159, 10, 1);
$iOS-systemPink-dark: rgba(255, 55, 95, 1);
$iOS-systemPurple-dark: rgba(191, 90, 242, 1);
$iOS-systemRed-dark: rgba(255, 69, 58, 1);
$iOS-systemTeal-dark: rgba(100, 210, 255, 1);
$iOS-systemYellow-dark: rgba(255, 214, 10, 1);
$iOS-systemGray-dark: rgba(142, 142, 147, 1);
$iOS-systemGray2-dark: rgba(99, 99, 102, 1);
$iOS-systemGray3-dark: rgba(72, 72, 74, 1);
$iOS-systemGray4-dark: rgba(58, 58, 60, 1);
$iOS-systemGray5-dark: rgba(44, 44, 46, 1);
$iOS-systemGray6-dark: rgba(28, 28, 30, 1);
$iOS-label-dark: rgba(255, 255, 255, 1);
$iOS-secondaryLabel-dark: rgba(235, 235, 245, 0.6);
$iOS-tertiaryLabel-dark: rgba(235, 235, 245, 0.3);
$iOS-quaternaryLabel-dark: rgba(235, 235, 245, 0.2);
$iOS-placeholderText-dark: rgba(235, 235, 245, 0.3);
$iOS-separator-dark: rgba(84, 84, 88, 0.3);
$iOS-opaqueSeparator-dark: rgba(56, 56, 58, 1);
$iOS-link-dark: rgba(9, 132, 255, 1);
```
```scss
// iOS-colors-light.scss
$iOS-systemBlue: rgba(0, 122, 255, 1);
$iOS-systemGreen: rgba(52, 199, 89, 1);
$iOS-systemIndigo: rgba(88, 86, 214, 1);
$iOS-systemOrange: rgba(255, 149, 0, 1);
$iOS-systemPink: rgba(255, 45, 85, 1);
$iOS-systemPurple: rgba(175, 82, 222, 1);
$iOS-systemRed: rgba(255, 59, 48, 1);
$iOS-systemTeal: rgba(90, 200, 250, 1);
$iOS-systemYellow: rgba(255, 204, 0, 1);
$iOS-systemGray: rgba(142, 142, 147, 1);
$iOS-systemGray2: rgba(174, 174, 178, 1);
$iOS-systemGray3: rgba(199, 199, 204, 1);
$iOS-systemGray4: rgba(209, 209, 214, 1);
$iOS-systemGray5: rgba(229, 229, 234, 1);
$iOS-systemGray6: rgba(242, 242, 247, 1);
$iOS-label: rgba(0, 0, 0, 1);
$iOS-secondaryLabel: rgba(60, 60, 67, 0.6);
$iOS-tertiaryLabel: rgba(60, 60, 67, 0.3);
$iOS-quaternaryLabel: rgba(60, 60, 67, 0.2);
$iOS-placeholderText: rgba(60, 60, 67, 0.3);
$iOS-separator: rgba(60, 60, 67, 0.3);
$iOS-opaqueSeparator: rgba(198, 198, 200, 1);
$iOS-link: rgba(0, 122, 255, 1);
```
@@ -0,0 +1,131 @@
$iOS-systemBlue: rgba(0, 122, 255, 1);
$iOS-systemGreen: rgba(52, 199, 89, 1);
$iOS-systemIndigo: rgba(88, 86, 214, 1);
$iOS-systemOrange: rgba(255, 149, 0, 1);
$iOS-systemPink: rgba(255, 45, 85, 1);
$iOS-systemPurple: rgba(175, 82, 222, 1);
$iOS-systemRed: rgba(255, 59, 48, 1);
$iOS-systemTeal: rgba(90, 200, 250, 1);
$iOS-systemYellow: rgba(255, 204, 0, 1);
$iOS-systemGray: rgba(142, 142, 147, 1);
$iOS-systemGray2: rgba(174, 174, 178, 1);
$iOS-systemGray3: rgba(199, 199, 204, 1);
$iOS-systemGray4: rgba(209, 209, 214, 1);
$iOS-systemGray5: rgba(229, 229, 234, 1);
$iOS-systemGray6: rgba(242, 242, 247, 1);
$iOS-label: rgba(0, 0, 0, 1);
$iOS-secondaryLabel: rgba(60, 60, 67, 0.6);
$iOS-tertiaryLabel: rgba(60, 60, 67, 0.3);
$iOS-quaternaryLabel: rgba(60, 60, 67, 0.2);
$iOS-placeholderText: rgba(60, 60, 67, 0.3);
$iOS-separator: rgba(60, 60, 67, 0.3);
$iOS-opaqueSeparator: rgba(198, 198, 200, 1);
$iOS-link: rgba(0, 122, 255, 1);
$iOS-systemBlue-dark: rgba(10, 132, 255, 1);
$iOS-systemGreen-dark: rgba(48, 209, 88, 1);
$iOS-systemIndigo-dark: rgba(94, 92, 230, 1);
$iOS-systemOrange-dark: rgba(255, 159, 10, 1);
$iOS-systemPink-dark: rgba(255, 55, 95, 1);
$iOS-systemPurple-dark: rgba(191, 90, 242, 1);
$iOS-systemRed-dark: rgba(255, 69, 58, 1);
$iOS-systemTeal-dark: rgba(100, 210, 255, 1);
$iOS-systemYellow-dark: rgba(255, 214, 10, 1);
$iOS-systemGray-dark: rgba(142, 142, 147, 1);
$iOS-systemGray2-dark: rgba(99, 99, 102, 1);
$iOS-systemGray3-dark: rgba(72, 72, 74, 1);
$iOS-systemGray4-dark: rgba(58, 58, 60, 1);
$iOS-systemGray5-dark: rgba(44, 44, 46, 1);
$iOS-systemGray6-dark: rgba(28, 28, 30, 1);
$iOS-label-dark: rgba(255, 255, 255, 1);
$iOS-secondaryLabel-dark: rgba(235, 235, 245, 0.6);
$iOS-tertiaryLabel-dark: rgba(235, 235, 245, 0.3);
$iOS-quaternaryLabel-dark: rgba(235, 235, 245, 0.2);
$iOS-placeholderText-dark: rgba(235, 235, 245, 0.3);
$iOS-separator-dark: rgba(84, 84, 88, 0.3);
$iOS-opaqueSeparator-dark: rgba(56, 56, 58, 1);
$iOS-link-dark: rgba(9, 132, 255, 1);
$macOS-systemBlue: rgba(0, 122, 255, 1);
$macOS-systemBrown: rgba(162, 132, 94, 1);
$macOS-systemGray: rgba(142, 142, 147, 1);
$macOS-systemGreen: rgba(40, 205, 65, 1);
$macOS-systemIndigo: rgba(88, 86, 214, 1);
$macOS-systemOrange: rgba(255, 149, 0, 1);
$macOS-systemPink: rgba(255, 45, 85, 1);
$macOS-systemPurple: rgba(175, 82, 222, 1);
$macOS-systemRed: rgba(255, 59, 48, 1);
$macOS-systemTeal: rgba(90, 200, 250, 1);
$macOS-systemYellow: rgba(255, 204, 0, 1);
$macOS-alternateSelectedControl: rgba(0, 99, 255, 1);
$macOS-alternateSelectedControlText: rgba(255, 255, 255, 1);
$macOS-controlBackground: rgba(255, 255, 255, 1);
$macOS-controlText: rgba(0, 0, 0, 0.8);
$macOS-disabledControlText: rgba(0, 0, 0, 0.2);
$macOS-grid: rgba(204, 204, 204, 1);
$macOS-headerText: rgba(0, 0, 0, 0.8);
$macOS-highlight: rgba(255, 255, 255, 1);
$macOS-labelColor: rgba(0, 0, 0, 0.8);
$macOS-linkColor: rgba(0, 104, 218, 1);
$macOS-placeholderTextColor: rgba(0, 0, 0, 0.2);
$macOS-quaternaryLabelColor: rgba(0, 0, 0, 0.1);
$macOS-secondaryLabelColor: rgba(0, 0 ,0, 0.5);
$macOS-selectedContentBackgroundColor: rgba(0, 99, 225, 1);
$macOS-selectedControlColor: rgba(179, 215, 255, 1);
$macOS-selectedControlTextColor: rgba(0, 0, 0, 0.8);
$macOS-selectedMenuItemTextColor: rgba(255, 255, 255, 1);
$macOS-selectedTextBackgroundColor: rgba(179, 215, 255, 1);
$macOS-selectedTextColor: rgba(0, 0, 0, 1);
$macOS-separatorColor: rgba(0, 0, 0, 0.1);
$macOS-shadowColor: rgba(0, 0, 0, 1);
$macOS-tertiaryLabelColor: rgba(0, 0, 0, 0.2);
$macOS-textBackgroundColor: rgba(255, 255, 255, 1);
$macOS-textColor: rgba(0, 0, 0, 1);
$macOS-underPageBackgroundColor: rgba(150, 150, 150, 0.9);
$macOS-unemphasizedSelectedContentBackgroundColor: rgba(220, 220, 220, 1);
$macOS-unemphasizedSelectedTextBackgroundColor: rgba(220, 220, 220, 1);
$macOS-unemphasizedSelectedTextColor: rgba(0, 0, 0, 1);
$macOS-windowBackgroundColor: rgba(236, 236, 236, 1);
$macOS-windowFrameTextColor: rgba(0, 0, 0, 0.8);
$macOS-systemBlue-dark: rgba(10, 132, 255, 1);
$macOS-systemBrown-dark: rgba(172, 142, 104, 1);
$macOS-systemGray-dark: rgba(152, 152, 157, 1);
$macOS-systemGreen-dark: rgba(50, 215, 75, 1);
$macOS-systemIndigo-dark: rgba(94, 92, 230, 1);
$macOS-systemOrange-dark: rgba(255, 159, 10, 1);
$macOS-systemPink-dark: rgba(255, 55, 95, 1);
$macOS-systemPurple-dark: rgba(191, 90, 242, 1);
$macOS-systemRed-dark: rgba(255, 69, 58, 1);
$macOS-systemTeal-dark: rgba(100, 210, 255, 1);
$macOS-systemYellow-dark: rgba(255, 214, 10, 1);
$macOS-alternateSelectedControl-dark: rgba(0, 88, 208, 1);
$macOS-alternateSelectedControlText-dark: rgba(255, 255, 255, 1);
$macOS-controlBackground-dark: rgba(30, 30, 30, 1);
$macOS-controlText-dark: rgba(255, 255, 255, 0.8);
$macOS-disabledControlText-dark: rgba(255, 255, 255, 0.2);
$macOS-grid-dark: rgba(255, 255, 255, 0.1);
$macOS-headerText-dark: rgba(255, 255, 255, 1);
$macOS-highlight-dark: rgba(180, 180, 180, 1);
$macOS-labelColor-dark: rgba(255, 255, 255, 0.8);
$macOS-linkColor-dark: rgba(65, 156, 255, 1);
$macOS-placeholderTextColor-dark: rgba(255, 255, 255, 0.2);
$macOS-quaternaryLabelColor-dark: rgba(255, 255, 255, 0.1);
$macOS-secondaryLabelColor-dark: rgba(255, 255, 255, 0.5);
$macOS-selectedContentBackgroundColor-dark: rgba(0, 88, 208, 1);
$macOS-selectedControlColor-dark: rgba(63, 99, 109, 1);
$macOS-selectedControlTextColor-dark: rgba(255, 255, 255, 0.8);
$macOS-selectedMenuItemTextColor-dark: rgba(255, 255, 255, 1);
$macOS-selectedTextBackgroundColor-dark: rgba(63, 99, 139, 1);
$macOS-selectedTextColor-dark: rgba(255, 255, 255, 1);
$macOS-separatorColor-dark: rgba(255, 255, 255, 0.1);
$macOS-shadowColor-dark: rgba(0, 0, 0, 0);
$macOS-tertiaryLabelColor-dark: rgba(255, 255, 255, 0.2);
$macOS-textBackgroundColor-dark: rgba(30, 30, 30, 1);
$macOS-textColor-dark: rgba(255, 255, 255, 1);
$macOS-underPageBackgroundColor-dark: rgba(40, 40, 40, 1);
$macOS-unemphasizedSelectedContentBackgroundColor-dark: rgba(70, 70, 70, 1);
$macOS-unemphasizedSelectedTextBackgroundColor-dark: rgba(70, 70, 70, 1);
$macOS-unemphasizedSelectedTextColor-dark: rgba(255, 255, 255, 1);
$macOS-windowBackgroundColor-dark: rgba(50, 50, 50, 1);
$macOS-windowFrameTextColor-dark: rgba(255, 255, 255, 0.8);
@@ -0,0 +1,51 @@
//
// Base styles
//
.alert {
position: relative;
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include border-radius($alert-border-radius);
}
// Headings for larger alerts
.alert-heading {
// Specified to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $close-font-size + $alert-padding-x * 2;
// Adjust close link position
.close {
position: absolute;
top: 0;
right: 0;
padding: $alert-padding-y $alert-padding-x;
color: inherit;
}
}
// scss-docs-start alert-modifiers
// Generate contextual modifier classes for colorizing the alert.
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include alert-variant(color-level($value, $alert-bg-level), color-level($value, $alert-border-level), color-level($value, $alert-color-level));
}
}
// scss-docs-end alert-modifiers
@@ -0,0 +1,29 @@
// Base class
//
// Requires one of the contextual, color modifier classes for `color` and
// `background-color`.
.badge {
display: inline-block;
padding: $badge-padding-y $badge-padding-x;
@include font-size($badge-font-size);
font-weight: $badge-font-weight;
line-height: 1;
color: $badge-color;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius($badge-border-radius);
@include gradient-bg();
// Empty badges collapse automatically
&:empty {
display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}
@@ -0,0 +1,30 @@
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
}
.breadcrumb-item {
display: flex;
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding-x;
&::before {
display: inline-block; // Suppress underlining of the separator
padding-right: $breadcrumb-item-padding-x;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
&.active {
color: $breadcrumb-active-color;
}
}
@@ -0,0 +1,141 @@
// stylelint-disable selector-no-qualifying-type
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
flex: 1 1 auto;
}
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
> .btn-check:checked + .btn,
> .btn-check:focus + .btn,
> .btn:hover,
> .btn:focus,
> .btn:active,
> .btn.active {
z-index: 1;
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.input-group {
width: auto;
}
}
.btn-group {
// Prevent double borders when buttons are next to each other
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-right-radius(0);
}
// The left radius should be 0 if the button is:
// - the "third or more" child
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
> .btn-group:not(:first-child) > .btn {
@include border-left-radius(0);
}
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-sm > .btn { @extend .btn-sm; }
.btn-group-lg > .btn { @extend .btn-lg; }
//
// Split button dropdowns
//
.dropdown-toggle-split {
padding-right: $btn-padding-x * .75;
padding-left: $btn-padding-x * .75;
&::after,
.dropup &::after,
.dropright &::after {
margin-left: 0;
}
.dropleft &::before {
margin-right: 0;
}
}
.btn-sm + .dropdown-toggle-split {
padding-right: $btn-padding-x-sm * .75;
padding-left: $btn-padding-x-sm * .75;
}
.btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * .75;
padding-left: $btn-padding-x-lg * .75;
}
// The clickable button for toggling the menu
// Set the same inset shadow as the :active state
.btn-group.show .dropdown-toggle {
@include box-shadow($btn-active-box-shadow);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
@include box-shadow(none);
}
}
//
// Vertical button groups
//
.btn-group-vertical {
flex-direction: column;
align-items: flex-start;
justify-content: center;
> .btn,
> .btn-group {
width: 100%;
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-top: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-bottom-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
}
@@ -0,0 +1,124 @@
//
// Base styles
//
.btn {
display: inline-block;
font-family: $btn-font-family;
font-weight: $btn-font-weight;
line-height: $btn-line-height;
color: $body-color;
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
cursor: if($enable-button-pointers, pointer, null);
user-select: none;
background-color: transparent;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius);
@include transition($btn-transition);
&:hover {
color: $body-color;
text-decoration: if($link-hover-decoration == underline, none, null);
}
.btn-check:focus + &,
&:focus {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
.btn-check:checked + &,
.btn-check:active + &,
&:active,
&.active {
@include box-shadow($btn-active-box-shadow);
&:focus {
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
}
}
&:disabled,
&.disabled,
fieldset:disabled & {
pointer-events: none;
opacity: $btn-disabled-opacity;
@include box-shadow(none);
}
}
//
// Alternate buttons
//
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-outline-variant($value);
}
}
//
// Link buttons
//
// Make a button look and behave like a link
.btn-link {
font-weight: $font-weight-normal;
color: $btn-link-color;
text-decoration: $link-decoration;
&:hover {
color: $btn-link-hover-color;
text-decoration: $link-hover-decoration;
}
&:focus {
text-decoration: $link-hover-decoration;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
}
//
// Block button
//
.btn-block {
display: block;
width: 100%;
// Vertically space out multiple block buttons
+ .btn-block {
margin-top: $btn-block-spacing-y;
}
}
@@ -0,0 +1,240 @@
//
// Base styles
//
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: $card-height;
word-wrap: break-word;
background-color: $card-bg;
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius($card-inner-border-radius);
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius($card-inner-border-radius);
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
}
.card-body {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
padding: $card-spacer-y $card-spacer-x;
color: $card-color;
}
.card-title {
margin-bottom: $card-title-spacer-y;
}
.card-subtitle {
margin-top: -$card-title-spacer-y / 2;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
&:hover {
text-decoration: none;
}
+ .card-link {
margin-left: $card-spacer-x;
}
}
//
// Optional textual caps
//
.card-header {
padding: $card-cap-padding-y $card-cap-padding-x;
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: $card-cap-color;
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
&:first-child {
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
}
}
.card-footer {
padding: $card-cap-padding-y $card-cap-padding-x;
color: $card-cap-color;
background-color: $card-cap-bg;
border-top: $card-border-width solid $card-border-color;
&:last-child {
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: -$card-cap-padding-x / 2;
margin-bottom: -$card-cap-padding-y;
margin-left: -$card-cap-padding-x / 2;
border-bottom: 0;
@if $nav-tabs-link-active-bg != $card-bg {
.nav-link.active {
background-color: $card-bg;
border-bottom-color: $card-bg;
}
}
}
.card-header-pills {
margin-right: -$card-cap-padding-x / 2;
margin-left: -$card-cap-padding-x / 2;
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: $card-img-overlay-padding;
@include border-radius($card-inner-border-radius);
}
.card-img,
.card-img-top,
.card-img-bottom {
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius($card-inner-border-radius);
}
.card-img,
.card-img-bottom {
@include border-bottom-radius($card-inner-border-radius);
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: $card-group-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-bottom: 0;
+ .card {
margin-left: 0;
border-left: 0;
}
// Handle rounded corners
@if $enable-rounded {
&:not(:last-child) {
@include border-right-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-left-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-left-radius: 0;
}
}
}
}
}
}
//
// Accordion
//
.accordion {
> .card {
overflow: hidden;
&:not(:last-of-type) {
border-bottom: 0;
@include border-bottom-radius(0);
}
&:not(:first-of-type) {
@include border-top-radius(0);
}
> .card-header {
@include border-radius(0);
margin-bottom: -$card-border-width;
}
}
}
@@ -0,0 +1,195 @@
// Notes on the classes:
//
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
// we're preventing all actions instead
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
// the active slide is heading.
// 3. .active.carousel-item is the current slide.
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
// slide in its in-transition state. Only one of these occurs at a time.
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
// is the upcoming slide in transition.
.carousel {
position: relative;
}
.carousel.pointer-event {
touch-action: pan-y;
}
.carousel-inner {
position: relative;
width: 100%;
overflow: hidden;
@include clearfix();
}
.carousel-item {
position: relative;
display: none;
float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: block;
}
.carousel-item-next:not(.carousel-item-left),
.active.carousel-item-right {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-right),
.active.carousel-item-left {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item {
opacity: 0;
transition-property: opacity;
transform: none;
}
.carousel-item.active,
.carousel-item-next.carousel-item-left,
.carousel-item-prev.carousel-item-right {
z-index: 1;
opacity: 1;
}
.active.carousel-item-left,
.active.carousel-item-right {
z-index: 0;
opacity: 0;
@include transition(opacity 0s $carousel-transition-duration);
}
}
//
// Left/right controls for nav
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// Use flex for alignment (1-3)
display: flex; // 1. allow flex styles
align-items: center; // 2. vertically center contents
justify-content: center; // 3. horizontally center contents
width: $carousel-control-width;
color: $carousel-control-color;
text-align: center;
opacity: $carousel-control-opacity;
@include transition($carousel-control-transition);
// Hover/focus state
&:hover,
&:focus {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
}
}
.carousel-control-prev {
left: 0;
background-image: if($enable-gradients, linear-gradient(90deg, rgba($black, .25), rgba($black, .001)), null);
}
.carousel-control-next {
right: 0;
background-image: if($enable-gradients, linear-gradient(270deg, rgba($black, .25), rgba($black, .001)), null);
}
// Icons for within
.carousel-control-prev-icon,
.carousel-control-next-icon {
display: inline-block;
width: $carousel-control-icon-width;
height: $carousel-control-icon-width;
background-repeat: no-repeat;
background-position: 50%;
background-size: 100% 100%;
}
.carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg);
}
.carousel-control-next-icon {
background-image: escape-svg($carousel-control-next-icon-bg);
}
// Optional indicator pips
//
// Add an ordered list with the following class and add a list item for each
// slide your carousel holds.
.carousel-indicators {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
display: flex;
justify-content: center;
padding-left: 0; // override <ol> default
// Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width;
margin-left: $carousel-control-width;
list-style: none;
li {
box-sizing: content-box;
flex: 0 1 auto;
width: $carousel-indicator-width;
height: $carousel-indicator-height;
margin-right: $carousel-indicator-spacer;
margin-left: $carousel-indicator-spacer;
text-indent: -999px;
cursor: pointer;
background-color: $carousel-indicator-active-bg;
background-clip: padding-box;
// Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: $carousel-indicator-opacity;
@include transition($carousel-indicator-transition);
}
.active {
opacity: $carousel-indicator-active-opacity;
}
}
// Optional captions
//
//
.carousel-caption {
position: absolute;
right: (100% - $carousel-caption-width) / 2;
bottom: $carousel-caption-spacer;
left: (100% - $carousel-caption-width) / 2;
padding-top: $carousel-caption-padding-y;
padding-bottom: $carousel-caption-padding-y;
color: $carousel-caption-color;
text-align: center;
}
@@ -0,0 +1,36 @@
.close {
@include font-size($close-font-size);
font-weight: $close-font-weight;
line-height: 1;
color: $close-color;
text-shadow: $close-text-shadow;
opacity: .5;
// Override <a>'s hover style
&:hover {
color: $close-color;
text-decoration: none;
}
&:hover,
&:focus {
opacity: .75;
}
&:disabled,
&.disabled {
pointer-events: none;
}
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
// stylelint-disable-next-line selector-no-qualifying-type
button.close {
padding: 0;
background-color: transparent;
border: 0;
}
@@ -0,0 +1,41 @@
// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.
@if $enable-grid-classes {
// Single container class with breakpoint max-widths
.container,
// 100% wide container at all breakpoints
.container-fluid {
@include make-container();
}
// Responsive containers that are 100% wide until a breakpoint
@each $breakpoint, $container-max-width in $container-max-widths {
.container-#{$breakpoint} {
@extend .container-fluid;
}
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
%responsive-container-#{$breakpoint} {
max-width: $container-max-width;
}
// Extend each breakpoint which is smaller or equal to the current breakpoint
$extend-breakpoint: true;
@each $name, $width in $grid-breakpoints {
@if ($extend-breakpoint) {
.container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
// Once the current breakpoint is reached, stop extending
@if ($breakpoint == $name) {
$extend-breakpoint: false;
}
}
}
}
}
}
@@ -0,0 +1,195 @@
// The dropdown wrapper (`<div>`)
.dropup,
.dropright,
.dropdown,
.dropleft {
position: relative;
}
.dropdown-toggle {
white-space: nowrap;
// Generate the caret automatically
@include caret();
}
// The dropdown menu
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: $zindex-dropdown;
display: none; // none by default, but block on "open" of the menu
min-width: $dropdown-min-width;
padding: $dropdown-padding-y 0;
margin: $dropdown-spacer 0 0; // override default ul
@include font-size($dropdown-font-size);
color: $dropdown-color;
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
list-style: none;
background-color: $dropdown-bg;
background-clip: padding-box;
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($dropdown-border-radius);
@include box-shadow($dropdown-box-shadow);
}
// scss-docs-start responsive-breakpoints
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-left {
right: auto;
left: 0;
}
.dropdown-menu#{$infix}-right {
right: 0;
left: auto;
}
}
}
// scss-docs-end responsive-breakpoints
// Allow for dropdowns to go bottom up (aka, dropup-menu)
// Just add .dropup after the standard .dropdown class and you're set.
.dropup {
.dropdown-menu {
top: auto;
bottom: 100%;
margin-top: 0;
margin-bottom: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(up);
}
}
.dropright {
.dropdown-menu {
top: 0;
right: auto;
left: 100%;
margin-top: 0;
margin-left: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(right);
&::after {
vertical-align: 0;
}
}
}
.dropleft {
.dropdown-menu {
top: 0;
right: 100%;
left: auto;
margin-top: 0;
margin-right: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(left);
&::before {
vertical-align: 0;
}
}
}
// When enabled Popper.js, reset basic dropdown position
// stylelint-disable-next-line no-duplicate-selectors
.dropdown-menu {
&[x-placement^="top"],
&[x-placement^="right"],
&[x-placement^="bottom"],
&[x-placement^="left"] {
right: auto;
bottom: auto;
}
}
// Dividers (basically an `<hr>`) within the dropdown
.dropdown-divider {
height: 0;
margin: $dropdown-divider-margin-y 0;
overflow: hidden;
border-top: 1px solid $dropdown-divider-bg;
}
// Links, buttons, and more within the dropdown menu
//
// `<button>`-specific styles are denoted with `// For <button>s`
.dropdown-item {
display: block;
width: 100%; // For `<button>`s
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
text-align: inherit; // For `<button>`s
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
// Prevent dropdown overflow if there's no padding
// See https://github.com/twbs/bootstrap/pull/27703
@if $dropdown-padding-y == 0 {
&:first-child {
@include border-top-radius($dropdown-inner-border-radius);
}
&:last-child {
@include border-bottom-radius($dropdown-inner-border-radius);
}
}
&:hover,
&:focus {
color: $dropdown-link-hover-color;
text-decoration: if($link-hover-decoration == underline, none, null);
@include gradient-bg($dropdown-link-hover-bg);
}
&.active,
&:active {
color: $dropdown-link-active-color;
text-decoration: none;
@include gradient-bg($dropdown-link-active-bg);
}
&.disabled,
&:disabled {
color: $dropdown-link-disabled-color;
pointer-events: none;
background-color: transparent;
// Remove CSS gradients if they're enabled
background-image: if($enable-gradients, none, null);
}
}
.dropdown-menu.show {
display: block;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: $dropdown-header-padding;
margin-bottom: 0; // for use with heading elements
@include font-size($font-size-sm);
color: $dropdown-header-color;
white-space: nowrap; // as with > li > a
}
// Dropdown text
.dropdown-item-text {
display: block;
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
color: $dropdown-link-color;
}
@@ -0,0 +1,9 @@
@import "forms/labels";
@import "forms/form-text";
@import "forms/form-control";
@import "forms/form-select";
@import "forms/form-check";
@import "forms/form-file";
@import "forms/form-range";
@import "forms/input-group";
@import "forms/validation";
@@ -0,0 +1,203 @@
// Bootstrap functions
//
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
// Ascending
// Used to evaluate Sass maps like our grid breakpoints.
@mixin _assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
// Do nothing
} @else if not comparable($prev-num, $num) {
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
} @else if $prev-num >= $num {
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
}
$prev-key: $key;
$prev-num: $num;
}
}
// Starts at zero
// Used to ensure the min-width of the lowest breakpoint starts at 0.
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
@if length($map) > 0 {
$values: map-values($map);
$first-value: nth($values, 1);
@if $first-value != 0 {
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
}
}
}
// Internal Bootstrap function to turn maps into its negative variant.
// It prefixes the keys with `n` and makes the value negative.
@function negativify-map($map) {
$result: ();
@each $key, $value in $map {
@if $key != 0 {
$result: map-merge($result, ("n" + $key: (-$value)));
}
}
@return $result;
}
// Get multiple keys from a sass map
@function map-get-multiple($map, $values) {
$result: ();
@each $key, $value in $map {
@if (index($values, $key) != null) {
$result: map-merge($result, ($key: $value));
}
}
@return $result;
}
// Replace `$search` with `$replace` in `$string`
// Used on our SVG icon backgrounds for custom forms.
//
// @author Hugo Giraudel
// @param {String} $string - Initial string
// @param {String} $search - Substring to replace
// @param {String} $replace ('') - New value
// @return {String} - Updated string
@function str-replace($string, $search, $replace: "") {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
// See https://codepen.io/kevinweber/pen/dXWoRw
@function escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $escaped-characters {
// Do not escape the url brackets
@if str-index($string, "url(") == 1 {
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
} @else {
$string: str-replace($string, $char, $encoded);
}
}
}
@return $string;
}
// Color contrast
// See https://github.com/twbs/bootstrap/pull/30168
// A list of pre-calculated numbers of pow(($value / 255 + .055) / 1.055, 2.4). (from 0 to 255)
// stylelint-disable-next-line scss/dollar-variable-default, scss/dollar-variable-pattern
$_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1;
@function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) {
$foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black;
$max-ratio: 0;
$max-ratio-color: null;
@each $color in $foregrounds {
$contrast-ratio: contrast-ratio($background, $color);
@if $contrast-ratio > $min-contrast-ratio {
@return $color;
} @else if $contrast-ratio > $max-ratio {
$max-ratio: $contrast-ratio;
$max-ratio-color: $color;
}
}
@warn "Found no color leading to #{$min-contrast-ratio}:1 contrast ratio against #{$background}";
@return $max-ratio-color;
}
@function contrast-ratio($background, $foreground: $color-contrast-light) {
$l1: luminance($background);
$l2: luminance(opaque($background, $foreground));
@return if($l1 > $l2, ($l1 + .05) / ($l2 + .05), ($l2 + .05) / ($l1 + .05));
}
// Return WCAG2.0 relative luminance
// See https://www.w3.org/WAI/GL/wiki/Relative_luminance
// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
@function luminance($color) {
$rgb: (
"r": red($color),
"g": green($color),
"b": blue($color)
);
@each $name, $value in $rgb {
$value: if($value / 255 < .03928, $value / 255 / 12.92, nth($_luminance-list, $value + 1));
$rgb: map-merge($rgb, ($name: $value));
}
@return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722);
}
// Return opaque color
// opaque(#fff, rgba(0, 0, 0, .5)) => #808080
@function opaque($background, $foreground) {
@return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);
}
// Request a color level
// scss-docs-start color-level
@function color-level($color: $primary, $level: 0) {
$color-base: if($level > 0, $black, $white);
$level: abs($level);
@return mix($color-base, $color, $level * $theme-color-interval);
}
// scss-docs-end color-level
@function tint-color($color, $level) {
@return mix(white, $color, $level * $theme-color-interval);
}
@function shade-color($color, $level) {
@return mix(black, $color, $level * $theme-color-interval);
}
// Return valid calc
@function add($value1, $value2, $return-calc: true) {
@if $value1 == null {
@return $value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 + $value2;
}
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
}
@function subtract($value1, $value2, $return-calc: true) {
@if $value1 == null and $value2 == null {
@return null;
}
@if $value1 == null {
@return -$value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 - $value2;
}
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
}
@@ -0,0 +1,22 @@
// Row
//
// Rows contain your columns.
@if $enable-grid-classes {
.row {
@include make-row();
> * {
@include make-col-ready();
}
}
}
// Columns
//
// Common styles for small and large grid columns
@if $enable-grid-classes {
@include make-grid-columns();
}
@@ -0,0 +1,7 @@
@import "helpers/clearfix";
@import "helpers/colored-links";
@import "helpers/embed";
@import "helpers/position";
@import "helpers/screenreaders";
@import "helpers/stretched-link";
@import "helpers/text-truncation";
@@ -0,0 +1,42 @@
// Responsive images (ensure images don't scale beyond their parents)
//
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
// which weren't expecting the images within themselves to be involuntarily resized.
// See also https://github.com/twbs/bootstrap/issues/18178
.img-fluid {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include img-fluid();
}
//
// Figures
//
.figure {
// Ensures the caption's text aligns with the image.
display: inline-block;
}
.figure-img {
margin-bottom: $spacer / 2;
line-height: 1;
}
.figure-caption {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}
@@ -0,0 +1,157 @@
// Base class
//
// Easily usable on <ul>, <ol>, or <div>.
.list-group {
display: flex;
flex-direction: column;
// No need to set list-style: none; since .list-group-item is block level
padding-left: 0; // reset padding because ul and ol
margin-bottom: 0;
@include border-radius($list-group-border-radius);
}
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive
// list items. Includes an extra `.active` modifier class for selected items.
.list-group-item-action {
width: 100%; // For `<button>`s (anchors become 100% by default though)
color: $list-group-action-color;
text-align: inherit; // For `<button>`s (anchors inherit)
// Hover state
&:hover,
&:focus {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
color: $list-group-action-hover-color;
text-decoration: none;
background-color: $list-group-hover-bg;
}
&:active {
color: $list-group-action-active-color;
background-color: $list-group-action-active-bg;
}
}
// Individual list items
//
// Use on `li`s or `div`s within the `.list-group` parent.
.list-group-item {
position: relative;
display: block;
padding: $list-group-item-padding-y $list-group-item-padding-x;
color: $list-group-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $list-group-bg;
border: $list-group-border-width solid $list-group-border-color;
&:first-child {
@include border-top-radius(inherit);
}
&:last-child {
@include border-bottom-radius(inherit);
}
&.disabled,
&:disabled {
color: $list-group-disabled-color;
pointer-events: none;
background-color: $list-group-disabled-bg;
}
// Include both here for `<a>`s and `<button>`s
&.active {
z-index: 2; // Place active items above their siblings for proper border styling
color: $list-group-active-color;
background-color: $list-group-active-bg;
border-color: $list-group-active-border-color;
}
& + & {
border-top-width: 0;
&.active {
margin-top: -$list-group-border-width;
border-top-width: $list-group-border-width;
}
}
}
// Horizontal
//
// Change the layout of list group items from vertical (default) to horizontal.
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.list-group-horizontal#{$infix} {
flex-direction: row;
> .list-group-item {
&:first-child {
@include border-bottom-left-radius($list-group-border-radius);
@include border-top-right-radius(0);
}
&:last-child {
@include border-top-right-radius($list-group-border-radius);
@include border-bottom-left-radius(0);
}
&.active {
margin-top: 0;
}
& + .list-group-item {
border-top-width: $list-group-border-width;
border-left-width: 0;
&.active {
margin-left: -$list-group-border-width;
border-left-width: $list-group-border-width;
}
}
}
}
}
}
// Flush list items
//
// Remove borders and border-radius to keep list group items edge-to-edge. Most
// useful within other components (e.g., cards).
.list-group-flush {
@include border-radius(0);
> .list-group-item {
border-width: 0 0 $list-group-border-width;
&:last-child {
border-bottom-width: 0;
}
}
}
// scss-docs-start list-group-modifiers
// List group contextual variants
//
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.
@each $color, $value in $theme-colors {
@include list-group-item-variant($color, color-level($value, $list-group-item-bg-level), color-level($value, $list-group-item-color-level));
}
// scss-docs-end list-group-modifiers
@@ -0,0 +1,41 @@
// Toggles
//
// Used in conjunction with global variables to enable certain theme features.
// Vendor
@import "vendor/rfs";
// Deprecate
@import "mixins/deprecate";
// Helpers
@import "mixins/breakpoints";
@import "mixins/image";
@import "mixins/resize";
@import "mixins/screen-reader";
@import "mixins/reset-text";
@import "mixins/text-truncate";
// Utilities
@import "mixins/utilities";
// Components
@import "mixins/alert";
@import "mixins/buttons";
@import "mixins/caret";
@import "mixins/pagination";
@import "mixins/lists";
@import "mixins/list-group";
@import "mixins/forms";
@import "mixins/table-variants";
// Skins
@import "mixins/border-radius";
@import "mixins/box-shadow";
@import "mixins/gradients";
@import "mixins/transition";
// Layout
@import "mixins/clearfix";
@import "mixins/container";
@import "mixins/grid";
@@ -0,0 +1,235 @@
// .modal-open - body class for killing the scroll
// .modal - container to scroll within
// .modal-dialog - positioning shell for the actual modal
// .modal-content - actual modal w/ bg and corners and stuff
.modal-open {
// Kill the scroll on the body
overflow: hidden;
.modal {
overflow-x: hidden;
overflow-y: auto;
}
}
// Container that the modal scrolls within
.modal {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal;
display: none;
width: 100%;
height: 100%;
overflow: hidden;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
}
// Shell div to position the modal with bottom padding
.modal-dialog {
position: relative;
width: auto;
margin: $modal-dialog-margin;
// allow clicks to pass through for custom click handling to close modal
pointer-events: none;
// When fading in the modal, animate it to slide down
.modal.fade & {
@include transition($modal-transition);
transform: $modal-fade-transform;
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
}
.modal-dialog-scrollable {
max-height: subtract(100%, $modal-dialog-margin * 2);
.modal-content {
overflow: hidden;
}
.modal-body {
overflow-y: auto;
}
}
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: subtract(100%, $modal-dialog-margin * 2);
}
// Actual modal
.modal-content {
position: relative;
display: flex;
flex-direction: column;
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
// counteract the pointer-events: none; in the .modal-dialog
color: $modal-content-color;
pointer-events: auto;
background-color: $modal-content-bg;
background-clip: padding-box;
border: $modal-content-border-width solid $modal-content-border-color;
@include border-radius($modal-content-border-radius);
@include box-shadow($modal-content-box-shadow-xs);
// Remove focus outline from opened modal
outline: 0;
}
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal-backdrop;
width: 100vw;
height: 100vh;
background-color: $modal-backdrop-bg;
// Fade for backdrop
&.fade { opacity: 0; }
&.show { opacity: $modal-backdrop-opacity; }
}
// Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
display: flex;
flex-shrink: 0;
align-items: flex-start; // so the close btn always stays on the upper right corner
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
padding: $modal-header-padding;
border-bottom: $modal-header-border-width solid $modal-header-border-color;
@include border-top-radius($modal-content-inner-border-radius);
.close {
padding: $modal-header-padding;
// auto on the left force icon to the right even when there is no .modal-title
margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;
}
}
// Title text within header
.modal-title {
margin-bottom: 0;
line-height: $modal-title-line-height;
}
// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
position: relative;
// Enable `flex-grow: 1` so that the body take up as much space as possible
// when there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: $modal-inner-padding;
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-wrap: wrap;
flex-shrink: 0;
align-items: center; // vertically center
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
padding: $modal-inner-padding - $modal-footer-margin-between / 2;
border-top: $modal-footer-border-width solid $modal-footer-border-color;
@include border-bottom-radius($modal-content-inner-border-radius);
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
> * {
margin: $modal-footer-margin-between / 2;
}
}
// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
// Scale up the modal
@include media-breakpoint-up(sm) {
// Automatically set modal's width for larger viewports
.modal-dialog {
max-width: $modal-md;
margin: $modal-dialog-margin-y-sm-up auto;
}
.modal-dialog-scrollable {
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
}
.modal-dialog-centered {
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
}
.modal-content {
@include box-shadow($modal-content-box-shadow-sm-up);
}
.modal-sm { max-width: $modal-sm; }
}
@include media-breakpoint-up(lg) {
.modal-lg,
.modal-xl {
max-width: $modal-lg;
}
}
@include media-breakpoint-up(xl) {
.modal-xl { max-width: $modal-xl; }
}
@each $breakpoint in map-keys($grid-breakpoints) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
$postfix: if($infix != "", $infix + "-down", "");
@include media-breakpoint-down($breakpoint) {
.modal-fullscreen#{$postfix} {
width: 100vw;
max-width: none;
height: 100%;
margin: 0;
.modal-content {
height: 100%;
border: 0;
@include border-radius(0);
}
.modal-header {
@include border-radius(0);
}
.modal-body {
overflow-y: auto;
}
.modal-footer {
@include border-radius(0);
}
}
}
}
@@ -0,0 +1,123 @@
// Base class
//
// Kickstart any navigation component with a set of style resets. Works with
// `<nav>`s, `<ul>`s or `<ol>`s.
.nav {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.nav-link {
display: block;
padding: $nav-link-padding-y $nav-link-padding-x;
text-decoration: if($link-decoration == none, null, none);
@include transition($nav-link-transition);
&:hover,
&:focus {
text-decoration: if($link-hover-decoration == underline, none, null);
}
// Disabled state lightens text
&.disabled {
color: $nav-link-disabled-color;
pointer-events: none;
cursor: default;
}
}
//
// Tabs
//
.nav-tabs {
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
.nav-link {
margin-bottom: -$nav-tabs-border-width;
border: $nav-tabs-border-width solid transparent;
@include border-top-radius($nav-tabs-border-radius);
&:hover,
&:focus {
border-color: $nav-tabs-link-hover-border-color;
}
&.disabled {
color: $nav-link-disabled-color;
background-color: transparent;
border-color: transparent;
}
}
.nav-link.active,
.nav-item.show .nav-link {
color: $nav-tabs-link-active-color;
background-color: $nav-tabs-link-active-bg;
border-color: $nav-tabs-link-active-border-color;
}
.dropdown-menu {
// Make dropdown border overlap tab border
margin-top: -$nav-tabs-border-width;
// Remove the top rounded corners here since there is a hard edge above the menu
@include border-top-radius(0);
}
}
//
// Pills
//
.nav-pills {
.nav-link {
@include border-radius($nav-pills-border-radius);
}
.nav-link.active,
.show > .nav-link {
color: $nav-pills-link-active-color;
@include gradient-bg($nav-pills-link-active-bg);
}
}
//
// Justified variants
//
.nav-fill {
> .nav-link,
.nav-item {
flex: 1 1 auto;
text-align: center;
}
}
.nav-justified {
> .nav-link,
.nav-item {
flex-basis: 0;
flex-grow: 1;
text-align: center;
}
}
// Tabbable tabs
//
// Hide tabbable panes to start, show them when `.active`
.tab-content {
> .tab-pane {
display: none;
}
> .active {
display: block;
}
}
@@ -0,0 +1,292 @@
// Contents
//
// Navbar
// Navbar brand
// Navbar nav
// Navbar text
// Responsive navbar
// Navbar position
// Navbar themes
// Navbar
//
// Provide a static navbar from which we expand to create full-width, fixed, and
// other navbar variations.
.navbar {
position: relative;
display: flex;
flex-wrap: wrap; // allow us to do the line break for collapsing content
align-items: center;
justify-content: space-between; // space out brand from logo
padding-top: $navbar-padding-y;
padding-right: $navbar-padding-x; // default: null
padding-bottom: $navbar-padding-y;
padding-left: $navbar-padding-x; // default: null
@include gradient-bg();
// Because flex properties aren't inherited, we need to redeclare these first
// few properties so that content nested within behave properly.
// The `flex-wrap` property is inherited to simplify the expanded navbars
%container-flex-properties {
display: flex;
flex-wrap: inherit;
align-items: center;
justify-content: space-between;
}
> .container,
> .container-fluid {
@extend %container-flex-properties;
}
@each $breakpoint, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
@extend %container-flex-properties;
}
}
}
// Navbar brand
//
// Used for brand, project, or site names.
.navbar-brand {
padding-top: $navbar-brand-padding-y;
padding-bottom: $navbar-brand-padding-y;
margin-right: $navbar-brand-margin-right;
@include font-size($navbar-brand-font-size);
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap;
&:hover,
&:focus {
text-decoration: if($link-hover-decoration == underline, none, null);
}
}
// Navbar nav
//
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
.navbar-nav {
display: flex;
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
padding-left: 0;
margin-bottom: 0;
list-style: none;
.nav-link {
padding-right: 0;
padding-left: 0;
}
.dropdown-menu {
position: static;
}
}
// Navbar text
//
//
.navbar-text {
padding-top: $nav-link-padding-y;
padding-bottom: $nav-link-padding-y;
}
// Responsive navbar
//
// Custom styles for responsive collapsing and toggling of navbar contents.
// Powered by the collapse Bootstrap JavaScript plugin.
// When collapsed, prevent the toggleable navbar contents from appearing in
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// on the `.navbar` parent.
.navbar-collapse {
// For always expanded or extra full navbars, ensure content aligns itself
// properly vertically. Can be easily overridden with flex utilities.
align-items: center;
width: 100%;
}
// Button for toggling the navbar when in its collapsed state
.navbar-toggler {
padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
@include font-size($navbar-toggler-font-size);
line-height: 1;
background-color: transparent; // remove default button style
border: $border-width solid transparent; // remove default button style
@include border-radius($navbar-toggler-border-radius);
@include transition($navbar-toggler-transition);
&:hover {
text-decoration: none;
}
&:focus {
text-decoration: none;
outline: 0;
box-shadow: 0 0 0 $navbar-toggler-focus-width;
}
}
// Keep as a separate element so folks can easily override it with another icon
// or image file as needed.
.navbar-toggler-icon {
display: inline-block;
width: 1.5em;
height: 1.5em;
vertical-align: middle;
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
}
// Generate series of `.navbar-expand-*` responsive classes for configuring
// where your navbar collapses.
.navbar-expand {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-up($next) {
flex-wrap: nowrap;
justify-content: flex-start;
.navbar-nav {
flex-direction: row;
.dropdown-menu {
position: absolute;
}
.nav-link {
padding-right: $navbar-nav-link-padding-x;
padding-left: $navbar-nav-link-padding-x;
}
}
.navbar-collapse {
display: flex !important; // stylelint-disable-line declaration-no-important
}
.navbar-toggler {
display: none;
}
}
}
}
}
// Navbar themes
//
// Styles for switching between navbars with light or dark background.
// Dark links against a light background
.navbar-light {
.navbar-brand {
color: $navbar-light-brand-color;
&:hover,
&:focus {
color: $navbar-light-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-light-color;
&:hover,
&:focus {
color: $navbar-light-hover-color;
}
&.disabled {
color: $navbar-light-disabled-color;
}
}
.show > .nav-link,
.nav-link.active {
color: $navbar-light-active-color;
}
}
.navbar-toggler {
color: $navbar-light-color;
border-color: $navbar-light-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-light-toggler-icon-bg);
}
.navbar-text {
color: $navbar-light-color;
a,
a:hover,
a:focus {
color: $navbar-light-active-color;
}
}
}
// White links against a dark background
.navbar-dark {
.navbar-brand {
color: $navbar-dark-brand-color;
&:hover,
&:focus {
color: $navbar-dark-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-dark-color;
&:hover,
&:focus {
color: $navbar-dark-hover-color;
}
&.disabled {
color: $navbar-dark-disabled-color;
}
}
.show > .nav-link,
.nav-link.active {
color: $navbar-dark-active-color;
}
}
.navbar-toggler {
color: $navbar-dark-color;
border-color: $navbar-dark-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {
color: $navbar-dark-color;
a,
a:hover,
a:focus {
color: $navbar-dark-active-color;
}
}
}
@@ -0,0 +1,61 @@
.pagination {
display: flex;
@include list-unstyled();
}
.page-link {
position: relative;
display: block;
color: $pagination-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $pagination-bg;
border: $pagination-border-width solid $pagination-border-color;
&:hover {
z-index: 2;
color: $pagination-hover-color;
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: $pagination-hover-bg;
border-color: $pagination-hover-border-color;
}
&:focus {
z-index: 3;
outline: $pagination-focus-outline;
box-shadow: $pagination-focus-box-shadow;
}
}
.page-item {
&:not(:first-child) .page-link {
margin-left: $pagination-margin-left;
}
&.active .page-link {
z-index: 3;
color: $pagination-active-color;
@include gradient-bg($pagination-active-bg);
border-color: $pagination-active-border-color;
}
&.disabled .page-link {
color: $pagination-disabled-color;
pointer-events: none;
background-color: $pagination-disabled-bg;
border-color: $pagination-disabled-border-color;
}
}
//
// Sizing
//
@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius);
.pagination-lg {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $border-radius-sm);
}
@@ -0,0 +1,170 @@
.popover {
position: absolute;
top: 0;
left: 0;
z-index: $zindex-popover;
display: block;
max-width: $popover-max-width;
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size($popover-font-size);
// Allow breaking very long words so they don't overflow the popover's bounds
word-wrap: break-word;
background-color: $popover-bg;
background-clip: padding-box;
border: $popover-border-width solid $popover-border-color;
@include border-radius($popover-border-radius);
@include box-shadow($popover-box-shadow);
.popover-arrow {
position: absolute;
display: block;
width: $popover-arrow-width;
height: $popover-arrow-height;
margin: 0 $popover-border-radius;
&::before,
&::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-popover-top {
margin-bottom: $popover-arrow-height;
> .popover-arrow {
bottom: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
bottom: 0;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-outer-color;
}
&::after {
bottom: $popover-border-width;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-color;
}
}
}
.bs-popover-right {
margin-left: $popover-arrow-height;
> .popover-arrow {
left: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
left: 0;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-outer-color;
}
&::after {
left: $popover-border-width;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-color;
}
}
}
.bs-popover-bottom {
margin-top: $popover-arrow-height;
> .popover-arrow {
top: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
top: 0;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
border-bottom-color: $popover-arrow-outer-color;
}
&::after {
top: $popover-border-width;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
border-bottom-color: $popover-arrow-color;
}
}
// This will remove the popover-header's border just below the arrow
.popover-header::before {
position: absolute;
top: 0;
left: 50%;
display: block;
width: $popover-arrow-width;
margin-left: -$popover-arrow-width / 2;
content: "";
border-bottom: $popover-border-width solid $popover-header-bg;
}
}
.bs-popover-left {
margin-right: $popover-arrow-height;
> .popover-arrow {
right: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
right: 0;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
border-left-color: $popover-arrow-outer-color;
}
&::after {
right: $popover-border-width;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
border-left-color: $popover-arrow-color;
}
}
}
.bs-popover-auto {
&[x-placement^="top"] {
@extend .bs-popover-top;
}
&[x-placement^="right"] {
@extend .bs-popover-right;
}
&[x-placement^="bottom"] {
@extend .bs-popover-bottom;
}
&[x-placement^="left"] {
@extend .bs-popover-left;
}
}
// Offset the popover to account for the popover arrow
.popover-header {
padding: $popover-header-padding-y $popover-header-padding-x;
margin-bottom: 0; // Reset the default from Reboot
@include font-size($font-size-base);
color: $popover-header-color;
background-color: $popover-header-bg;
border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
@include border-top-radius($popover-inner-border-radius);
&:empty {
display: none;
}
}
.popover-body {
padding: $popover-body-padding-y $popover-body-padding-x;
color: $popover-body-color;
}
@@ -0,0 +1,45 @@
// Disable animation if transitions are disabled
@if $enable-transitions {
@keyframes progress-bar-stripes {
0% { background-position-x: $progress-height; }
}
}
.progress {
display: flex;
height: $progress-height;
overflow: hidden; // force rounded corners by cropping it
@include font-size($progress-font-size);
background-color: $progress-bg;
@include border-radius($progress-border-radius);
@include box-shadow($progress-box-shadow);
}
.progress-bar {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
color: $progress-bar-color;
text-align: center;
white-space: nowrap;
background-color: $progress-bar-bg;
@include transition($progress-bar-transition);
}
.progress-bar-striped {
@include gradient-striped();
background-size: $progress-height $progress-height;
}
@if $enable-transitions {
.progress-bar-animated {
animation: progress-bar-stripes $progress-bar-animation-timing;
@if $enable-reduced-motion {
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
}
}
@@ -0,0 +1,616 @@
// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
// Reboot
//
// Normalization of HTML elements, manually forked from Normalize.css to remove
// styles targeting irrelevant browsers while applying new styles.
//
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
// Document
//
// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
*,
*::before,
*::after {
box-sizing: border-box;
}
// Root
//
// Ability to the value of the root font sizes, affecting the value of `rem`.
// null by default, thus nothing is generated.
:root {
font-size: $font-size-root;
}
// Body
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
// 3. Prevent adjustments of font size after orientation changes in iOS.
// 4. Change the default tap highlight to be completely transparent in iOS.
body {
margin: 0; // 1
font-family: $font-family-base;
@include font-size($font-size-base);
font-weight: $font-weight-base;
line-height: $line-height-base;
color: $body-color;
text-align: $body-text-align;
background-color: $body-bg; // 2
-webkit-text-size-adjust: 100%; // 3
-webkit-tap-highlight-color: rgba($black, 0); // 4
}
// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline
// on elements that programmatically receive focus but wouldn't normally show a visible
// focus outline. In general, this would mean that the outline is only applied if the
// interaction that led to the element receiving programmatic focus was a keyboard interaction,
// or the browser has somehow determined that the user is primarily a keyboard user and/or
// wants focus outlines to always be presented.
// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
// Content grouping
//
// 1. Reset Firefox's gray color
// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field
// See https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_hr_size
hr {
margin: $hr-margin-y 0;
color: $hr-color; // 1
background-color: currentColor;
border: 0;
opacity: $hr-opacity;
}
hr:not([size]) {
height: $hr-height; // 2
}
// Typography
//
// 1. Remove top margins from headings
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
// margin for easier control within type scales as it avoids margin collapsing.
%heading {
margin-top: 0; // 1
margin-bottom: $headings-margin-bottom;
font-family: $headings-font-family;
font-style: $headings-font-style;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: $headings-color;
}
h1 {
@extend %heading;
@include font-size($h1-font-size);
}
h2 {
@extend %heading;
@include font-size($h2-font-size);
}
h3 {
@extend %heading;
@include font-size($h3-font-size);
}
h4 {
@extend %heading;
@include font-size($h4-font-size);
}
h5 {
@extend %heading;
@include font-size($h5-font-size);
}
h6 {
@extend %heading;
@include font-size($h6-font-size);
}
// Reset margins on paragraphs
//
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
// bottom margin to use `rem` units instead of `em`.
p {
margin-top: 0;
margin-bottom: $paragraph-margin-bottom;
}
// Abbreviations
//
// 1. Duplicate behavior to the data-* attribute for our tooltip plugin
// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
// 3. Add explicit cursor to indicate changed behavior.
// 4. Prevent the text-decoration to be skipped.
abbr[title],
abbr[data-original-title] { // 1
text-decoration: underline; // 2
text-decoration: underline dotted; // 2
cursor: help; // 3
text-decoration-skip-ink: none; // 4
}
// Address
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
// Lists
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: $dt-font-weight;
}
// 1. Undo browser default
dd {
margin-bottom: .5rem;
margin-left: 0; // 1
}
// Blockquote
blockquote {
margin: 0 0 1rem;
}
// Strong
//
// Add the correct font weight in Chrome, Edge, and Safari
b,
strong {
font-weight: $font-weight-bolder;
}
// Small
//
// Add the correct font size in all browsers
small {
@include font-size($small-font-size);
}
// Mark
mark {
padding: $mark-padding;
background-color: $mark-bg;
}
// Sub and Sup
//
// Prevent `sub` and `sup` elements from affecting the line height in
// all browsers.
sub,
sup {
position: relative;
@include font-size($sub-sup-font-size);
line-height: 0;
vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }
// Links
a {
color: $link-color;
text-decoration: $link-decoration;
&:hover {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// It would be more straightforward to just use a[href] in previous block, but that
// causes specificity issues in many other styles that are too complex to fix.
// See https://github.com/twbs/bootstrap/issues/19402
a:not([href]):not([class]) {
&,
&:hover {
color: inherit;
text-decoration: none;
}
}
// Code
pre,
code,
kbd,
samp {
font-family: $font-family-code;
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
}
// 1. Remove browser default top margin
// 2. Reset browser default of `1em` to use `rem`s
// 3. Don't allow content to break outside
// 4. Disable auto-hiding scrollbar in legacy Edge to avoid overlap,
// making it impossible to interact with the content
pre {
display: block;
margin-top: 0; // 1
margin-bottom: 1rem; // 2
overflow: auto; // 3
@include font-size($code-font-size);
color: $pre-color;
-ms-overflow-style: scrollbar; // 4
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
code {
@include font-size($code-font-size);
color: $code-color;
word-wrap: break-word;
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
kbd {
padding: $kbd-padding-y $kbd-padding-x;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
kbd {
padding: 0;
@include font-size(1em);
font-weight: $nested-kbd-font-weight;
}
}
// Figures
//
// Apply a consistent margin strategy (matches our type styles).
figure {
margin: 0 0 1rem;
}
// Images and content
img,
svg {
vertical-align: middle;
}
// Tables
//
// Prevent double borders
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: $table-cell-padding-y;
padding-bottom: $table-cell-padding-y;
color: $table-caption-color;
text-align: left;
}
// 1. Matches default `<td>` alignment by inheriting `text-align`.
// 2. Fix alignment for Safari
th {
text-align: inherit; // 1
text-align: -webkit-match-parent; // 2
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
// Forms
//
// 1. Allow labels to use `margin` for spacing.
label {
display: inline-block; // 1
}
// Remove the default `border-radius` that macOS Chrome adds.
// See https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-blacklist
border-radius: 0;
}
// Work around a Firefox bug where the transparent `button` background
// results in a loss of the default `button` focus styles.
// Credit https://github.com/suitcss/base/
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
// 1. Remove the margin in Firefox and Safari
input,
button,
select,
optgroup,
textarea {
margin: 0; // 1
font-family: inherit;
@include font-size(inherit);
line-height: inherit;
}
// Show the overflow in Edge
button,
input {
overflow: visible;
}
// Remove the inheritance of text transform in Firefox
button,
select {
text-transform: none;
}
// Set the cursor for non-`<button>` buttons
//
// Details at https://github.com/twbs/bootstrap/pull/30562
[role="button"] {
cursor: pointer;
}
// Remove the inheritance of word-wrap in Safari.
// See https://github.com/twbs/bootstrap/issues/24990
select {
word-wrap: normal;
}
// Remove the dropdown arrow in Chrome from inputs built with datalists.
// See https://stackoverflow.com/a/54997118
[list]::-webkit-calendar-picker-indicator {
display: none;
}
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
// controls in Android 4.
// 2. Correct the inability to style clickable types in iOS and Safari.
// 3. Opinionated: add "hand" cursor to non-disabled button elements.
button,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
@if $enable-button-pointers {
&:not(:disabled) {
cursor: pointer; // 3
}
}
}
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
::-moz-focus-inner {
padding: 0;
border-style: none;
}
// 1. Textareas should really only resize vertically so they don't break their (horizontal) containers.
textarea {
resize: vertical; // 1
}
// 1. Browsers set a default `min-width: min-content;` on fieldsets,
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
// So we reset that to ensure fieldsets behave more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
// 2. Reset the default outline behavior of fieldsets so they don't affect page layout.
fieldset {
min-width: 0; // 1
padding: 0; // 2
margin: 0; // 2
border: 0; // 2
}
// 1. By using `float: left`, the legend will behave like a block element.
// This way the border of a fieldset wraps around the legend if present.
// 2. Correct the text wrapping in Edge.
// 3. Fix wrapping bug.
// See https://github.com/twbs/bootstrap/issues/29712
legend {
float: left; // 1
width: 100%;
padding: 0;
margin-bottom: $legend-margin-bottom;
@include font-size($legend-font-size);
font-weight: $legend-font-weight;
line-height: inherit;
white-space: normal; // 2
+ * {
clear: left; // 3
}
}
// Fix height of inputs with a type of datetime-local, date, month, week, or time
// See https://github.com/twbs/bootstrap/issues/18842
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
// 1. Correct the outline style in Safari.
// 2. This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
[type="search"] {
outline-offset: -2px; // 1
-webkit-appearance: textfield; // 2
}
// Remove the inner padding in Chrome and Safari on macOS.
::-webkit-search-decoration {
-webkit-appearance: none;
}
// Remove padding around color pickers in webkit browsers
::-webkit-color-swatch-wrapper {
padding: 0;
}
// 1. Change font properties to `inherit` in Safari.
// 2. Correct the inability to style clickable types in iOS and Safari.
::-webkit-file-upload-button {
font: inherit; // 1
-webkit-appearance: button; // 2
}
// Correct element displays
output {
display: inline-block;
}
// Remove border from iframe
iframe {
border: 0;
}
// Summary
//
// 1. Add the correct display in all browsers
summary {
display: list-item; // 1
cursor: pointer;
}
// Progress
//
// Add the correct vertical alignment in Chrome, Firefox, and Opera.
progress {
vertical-align: baseline;
}
// Hidden attribute
//
// Always hide an element with the `hidden` HTML attribute.
[hidden] {
display: none !important;
}

Some files were not shown because too many files have changed in this diff Show More