Passen Sie die Helligkeit des Displays automatisch an Sonnenaufgang und Sonnenuntergang an


10

In Ask Ubuntu gibt es ähnliche Fragen und Antworten , die auf diese Lösungen hinweisen:

Entweder müssen die Sonnenauf- und -untergangszeiten manuell eingegeben werden, oder sie passen lediglich die Farbbalance an und fügen nachts mehr Rot hinzu.

Ich suche nach einer Lösung, die jeden Tag automatisch Sonnenauf- und -untergangszeiten ermittelt und die Helligkeit des Displays physisch anpasst. Außerdem möchte ich einen Übergangseffekt über einen Zeitraum von 60 bis 120 Minuten, damit ich die Änderung der Anzeige nicht bemerke.

Die Neukonfiguration an bewölkten Tagen (draußen dunkler) oder wenn die Sonne zwischen zwei dreistöckigen Gebäuden anstelle ihrer Dächer (heller vor Sonnenuntergang) untergeht, sollte ein schneller und einfacher Vorgang sein.

Antworten:


7

Aktualisierter Beitrag von 2019 - Eyesome

Eyesome ist ein Bash-Skript, das als Deamon ausgeführt wird und die meiste Zeit rund um die Uhr schläft. Mithilfe der Softwaresteuerung von xrandr wird die Bildschirmhelligkeit (und optional auch Gamma) für Ihr Laptop-Display automatisch über die Hardwareschnittstelle und bis zu zwei weitere Monitore angepasst.

Bei Sonnenaufgang (die Uhrzeit wird jeden Tag automatisch aus dem Internet abgerufen) wird die Bildschirmhelligkeit (und optional auch Gamma) schrittweise angepasst. Die schrittweise Anpassung wird von Ihnen festgelegt, aber 120 Minuten funktionieren für mich. Um die Einstellungen unbemerkt zu lassen, legen Sie ein Schlafintervall zwischen den Einstellungen fest. Ein Wert zwischen 15 und 60 Sekunden ist wahrscheinlich am besten und der Standardwert ist 60.

Eyesome Daemon schläft viele Stunden, bis der Übergang zum Sonnenuntergang beginnt. Im Gegensatz zum Sonnenaufgangsübergang verringert der Sonnenuntergangsübergang allmählich die Bildschirmhelligkeit (und optional auch Gamma), sodass er nicht wahrgenommen wird. 90 Minuten vor Sonnenuntergang wird empfohlen, Sie können jedoch einen beliebigen Zeitraum einstellen.

Während des Sonnenuntergangsübergangs kann definiert werden, dass das Gamma zunimmt. Zum Beispiel kann rotes Gamma als 1,0 während des Tages und 1,2 während der Nacht definiert werden, um die Belastung der Augen zu verringern. Blaues Gamma wiederum kann tagsüber als 1,0 und nachts als 0,8 definiert werden, sodass es stattdessen abnimmt.

Um die Ressourcen zu reduzieren, schläft Eyeome die gesamte Zeit zwischen Sonnenuntergang und Sonnenaufgang. Es gibt einmalige Ausnahmen, wenn externe Monitore angehalten oder heiß angeschlossen werden. Es hängt davon ab, wo Sie wohnen und zu welcher Jahreszeit, aber der durchschnittliche Schlaf beträgt 12 Stunden.

Sie können Eyesome von Github herunterladen


Ursprünglicher Beitrag von 2017

Einführung

Dies ist eine Bash-Lösung, bei der keine zusätzlichen Programme installiert werden müssen. Es ist eine Internetverbindung erforderlich (wenn Sie dies lesen, haben Sie eine), um jeden Tag automatisch Sonnenauf- und -untergangszeiten zu erhalten. Es bietet einen benutzerfreundlichen Konfigurationsbildschirm. Es startet automatisch mit cronund erfordert keine Benutzerinteraktion.

Diese Antwort ist in mehrere Teile unterteilt

  • Holen Sie sich automatisch Sonnenauf- und -untergangszeiten jeden Tag mit cron
  • Konfigurieren Sie die Helligkeitseinstellungen und die Übergangszeit
  • Hauptskript zum Anpassen der Helligkeit basierend auf der Tageszeit
  • Starten Sie die Anzeige-Auto-Helligkeit automatisch bei jedem Start mit cron
  • Sofortige / transparente Helligkeitsanpassung nach Suspendierung
  • Zusammenfassung

Mit cron erhalten Sie jeden Tag automatisch Sonnenauf- und -untergangszeiten

Es gibt viele Websites, auf denen Sonnenauf- und -untergangszeiten für Ihren Standort gemeldet werden können. Dieses Skript verwendet ( https://www.timeanddate.com/ ), eine seit langem bekannte Site.

Mit Sudo-Kräften bearbeiten Sie die Datei /usr/local/bin/sun-hoursund fügen sie ein:

#!/bin/bash

# Called daily from /etc/cron.daily/sun-hours
while true; do

### "-q"= quiet, "-O-" pipe output
echo $(wget -q -O- https://www.timeanddate.com/sun/canada/edmonton | grep -oE 'Sunrise Today.{35}' | awk -F\> '{print $3}' | tr --delete "<") > /tmp/sunrise
echo $(wget -q -O- https://www.timeanddate.com/sun/canada/edmonton | grep -oE 'Sunset Today.{35}' | awk -F\> '{print $3}' | tr --delete "<") > /tmp/sunset

## If network is down files will have one byte size
size1=$(wc -c < /tmp/sunrise)
size2=$(wc -c < /tmp/sunset)

if [ $size1 -gt 1 ] && [ $size2 -gt 1 ] ; then
    cp /tmp/sunrise /usr/local/bin/sunrise
    cp /tmp/sunset  /usr/local/bin/sunset
    chmod 666 /usr/local/bin/sunrise
    chmod 666 /usr/local/bin/sunset
    rm /tmp/sunrise
    rm /tmp/sunset
    exit 0
else
    logger "/etc/cron.daily/sun-hours: Network is down. Waiting 5 minutes to try again."
    sleep 300
fi

done

Ersetzen Sie vor dem Speichern des Skripts die beiden Vorkommen von /canada/edmontondurch Ihr eigenes Land und Ihre Stadt. Besuchen Sie die Website www.timeanddate.com, um den genauen Namen oder die genaue Nummer zu erhalten. Zum Beispiel hat "Paris, USA" Dutzende von Namen, so dass sie eine Nummer enthalten, wie zum Beispiel /worldclock/@5205082für "Paris, PA USA".

Verwenden Sie cron, um jeden Tag ein Sonnenstundenskript auszuführen

Mit Sudo-Kräften bearbeiten Sie die Datei /etc/cron.daily/sun-hoursund fügen sie ein:

#!/bin/sh
#
# Each day /etc/cron.daily/sun-hours will get sunrise and sunset times.

sleep 60 # give time for network to come up.
/usr/local/bin/sun-hours

Markieren Sie beide Dateien als ausführbar, sudo chmod a+x ___/sun-hourswobei "___" das Verzeichnis für jede Datei ist.

Verwenden Sie Conky, um Änderungen der Sonnenauf- und -untergangszeit jeden Tag zu überwachen

Conky ist ein beliebtes Tool zur Überwachung Ihres Systems. Hier sind die Befehle zum Anzeigen von Sonnenaufgang, Sonnenuntergang und Helligkeitseinstellung:

${color orange}${voffset 2}${hr 1}
${color}${goto 5}Day: ${color green}${execpi 300 cat /usr/local/bin/sunrise}  ${color}Night: ${color green}${execpi 300 cat /usr/local/bin/sunset}  ${color}Level: ${color green}${execpi 10 cat cat /sys/class/backlight/intel_backlight/brightness}
${color orange}${voffset 2}${hr 1}

So sieht es aus:

Display-Auto-Helligkeit conky

Hinweis: Dieser Conky-Code verwendet, intel_backlightden Sie abhängig von Ihrem Anzeigeadapter ändern müssen, wie in den folgenden Abschnitten beschrieben.

Konfigurieren Sie die Helligkeitseinstellungen und die Übergangszeit

Sie möchten nicht, dass Ihr Display bei Sonnenaufgang auf volle Helligkeit und bei Sonnenuntergang auf volle Dunkelheit wechselt. Eine Übergangszeit ist erforderlich. Zusätzlich ist eine Konfigurationsdatei erforderlich, um die Variablen für volle Helligkeit und volle Dunkelheit aufzuzeichnen. Dies ist der Konfigurationsbildschirm:

Display-Auto-Helligkeits-Konfiguration

Der Bildschirm wird mit dem Standardbefehl zenity erstellt. Daher werden vorhandene Werte in Beschriftungen mit dem Tag "(value)" angezeigt, und Sie geben bei Bedarf neue Werte ein. Andernfalls bleiben die vorhandenen Dateien erhalten, wenn neue Werte leer sind.

Ersetzen Sie ihn intel_backlightdurch Ihren Bildschirmtreiber, falls abweichend. Um Ihren Namen herauszufinden, verwenden Sie : ls /sys/class/backlight/*/brightness.

Erstellen Sie die Datei mit Sudo-Kräften /usr/local/bin/auto-brightness-configund fügen Sie sie in diesen Code ein:

#!/bin/bash

# Read hidden configuration file with entries separated by " " into array
IFS=' ' read -ra CfgArr < /usr/local/bin/.auto-brightness-config

# Zenity form with current values in entry label
# because initializing multiple entry data fields not supported
output=$(zenity --forms --title="Display Auto Brightness Configuration" \
        --text="Enter new settings or leave entries blank to keep (existing) settings" \
   --add-entry="/sys/class/backlight/??????/brightness driver : (${CfgArr[0]})" \
   --add-entry="Day time maximum display brightness : (${CfgArr[1]})" \
   --add-entry="Transition minutes after sunrise to maximum : (${CfgArr[2]})" \
   --add-entry="Night time minimum display brightness : (${CfgArr[3]})" \
   --add-entry="Transition minutes before sunset to minimum : (${CfgArr[4]})")

IFS='|' read -a ZenArr <<<$output # Split zenity entries separated by "|" into array elements

# Update non-blank zenity array entries into configuration array
for i in ${!ZenArr[@]}; do
    if [[ ${ZenArr[i]} != "" ]]; then CfgArr[i]=${ZenArr[i]} ; fi
done

# write hidden configuration file using array (fields automatically separated by " ")
echo "${CfgArr[@]}" > /usr/local/bin/.auto-brightness-config

Markieren Sie die Datei als ausführbar mit:

chmod a+x /usr/local/bin/auto-brightness-config

Hauptprogramm display-auto-brightness

Erstellen Sie die Datei mit Sudo-Kräften /usr/local/bin/display-auto-brightnessund fügen Sie sie in diesen Code ein:

#!/bin/bash

# NAME: display-auto-brightness
# PATH: /usr/local/bin
# DESC: Set display brightness based on min/max values, sun rise/set time
#       and transition minutes.
# CALL: Called from cron on system startup with @reboot option.
# DATE: Feb 17, 2017. Modified: Dec 2, 2017.

# NOTE: Only sleep for 1 minute to make display brightness changes gradual.
#       Configuration file can change any time so variables reread when waking.
#       The file is maintained by /usr/local/bin/auto-brightness-config script.

#       Sunrise and sunset time obtained from www.dateandtime.com using
#       /usr/local/bin/sun-hours script. The script is called from cron using
#       /etc/cron.daily/cron-daily-sun-hours. Variables stored in am/pm format
#       in /usr/local/bin/sunrise and /usr/local/bin/sunset.

#       When suspending at 6 am it might be dark with setting at 300. When 
#       resuming at 4:30pm it might be full sun and setting needs to be 2000.
#       It will take between 1 and 59 seconds to adjust screen brightness with
#       sudden jump in brightness. To correct this create kill sleep command
#       during suspend with /lib/systemd/system-sleep/display-auto-brightness
#       script.

# TODO: Add support for external monitors connected via HDMI / DisplayPort.
#       xrandr --output HDMI-0  --brightness .799
#       xrandr --output DP-1-1  --brightness 1.15

if [[ $(id -u) != 0 ]]; then # root powers needed to call this script
    echo display-auto-brightness must be called with sudo powers
    exit 1
fi

# global variable
LastSetting=""

function set-and-sleep {
    if [[ "$1" != "$LastSetting" ]]; then
        sudo sh -c "echo $1 | sudo tee $backlight"
        echo "$1" > "/tmp/display-current-brightness"
        LastSetting="$1"
    fi
    sleep 60
}  

re='^[0-9]+$'   # regex for valid numbers

function calc-level-and-sleep {
    # Parms $1 = number of minutes for total transition
    #       $2 = number of seconds into transition

    secTotal=$(( $1 * 60 )) # Convert total transition minutes to seconds
    Adjust=$( bc <<< "scale=6; $transition_spread * ( $2 / $secTotal )" )
    Adjust=$( echo $Adjust | cut -f1 -d"." ) # Truncate number to integer

    if ! [[ $Adjust =~ $re ]] ; then
        Adjust=0   # When we get to last minute $Adjust can be non-numeric
    fi

    calc_bright=$(( $min_bright + $Adjust ))
    set-and-sleep "$calc_bright"
}


while true ; do

    # Although variables change once a day it could be weeks between reboots.
    sunrise=$(cat /usr/local/bin/sunrise)
    sunset=$(cat /usr/local/bin/sunset)

    # Read hidden configuration file with entries separated by " " into array
    IFS=' ' read -ra CfgArr < /usr/local/bin/.auto-brightness-config
    backlight="/sys/class/backlight/${CfgArr[0]}/brightness"
    max_bright="${CfgArr[1]}"
    after_sunrise="${CfgArr[2]}"
    min_bright="${CfgArr[3]}"
    before_sunset="${CfgArr[4]}"

    # Current seconds
    secNow=$(date +"%s")
    secSunrise=$(date --date="$sunrise today" +%s)
    secSunset=$(date --date="$sunset today" +%s)

    # Is it night time?
    if [ "$secNow" -gt "$secSunset" ] || [ "$secNow" -lt "$secSunrise" ]; then
        # MINIMUN: after sunset or before sunrise nightime setting
        set-and-sleep "$min_bright"
        continue
    fi

    # We're somewhere between sunrise and sunset
    secMaxCutoff=$(( $secSunrise + ( $after_sunrise * 60 ) ))
    secMinStart=$((  $secSunset  - ( $before_sunset * 60 ) ))

    # Is it full bright day time?
    if [ "$secNow" -gt "$secMaxCutoff" ] && [ "$secNow" -lt "$secMinStart" ]; then
        # MAXIMUN: after sunrise transition AND before nightime transition
        set-and-sleep "$max_bright"
        continue
    fi

    # Daytime - nightime = transition brightness levels
    transition_spread=$(( $max_bright - $min_bright ))

    # Are we between sunrise and full brightness?
    if [ "$secNow" -gt "$secSunrise" ] && [ "$secNow" -lt "$secMaxCutoff" ]; then
        # Current time - Sunrise = progress through transition
        secPast=$(( $secNow - $secSunrise ))
        calc-level-and-sleep $after_sunrise $secPast
        continue
    fi

    # Are we between beginning to dim and sunset (full dim)?
    if [ "$secNow" -gt "$secMinStart" ] && [ "$secNow" -lt "$secSunset" ]; then
        # Sunset - Current time = progress through transition
        secBefore=$(( $secSunset - $secNow ))
        calc-level-and-sleep $before_sunset $secBefore
        continue
    fi

    # At this stage brightness was set with manual override outside this program
    # or exactly at a testpoint, then it will change next minute so no big deal.
    sleep 60 # reset brightness once / minute.

done # End of forever loop

Markieren Sie die Datei als ausführbar mit:

chmod a+x /usr/local/bin/display-auto-brightness

HINWEIS: Der 26. August 2017 wurde erfolglos überarbeitet, um den Fehler zu beheben, bei dem das Programm angehalten wurde, wenn die letzte Helligkeitsstufe der minimalen oder maximalen Helligkeit entsprach und der Anpassungswert der aktuellen Minute leer (Null) war. Erfolgreich behoben am 2. Dezember 2017, aber erst am 17. Februar 2018 veröffentlicht. Ups!

Starten Sie die Anzeige-Auto-Helligkeit automatisch bei jedem Start mit cron

Cron wird verwendet, um die Hauptanwendung bei jedem Start zu starten. Erstellen Sie die Datei /etc/cron.d/display-auto-brightnessmit Sudo-Kräften und kopieren Sie diese:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot   root    /usr/local/bin/display-auto-brightness

Sofortige Helligkeitsanpassung nach Suspendierung

Sie können Ihren Computer um 6 Uhr morgens anhalten, wenn die Sonne aufgeht, und Ihre Einstellung ist um 300 Uhr. Sie können ihn um 16 Uhr wieder aufnehmen, wenn die Sonne scheint und die Einstellung 2000 sein sollte, aber Sie müssen 1 bis 59 Sekunden warten, display-auto-brightnessbis Setzen Sie die Anzeige zurück. Wenn die Anzeige zurückgesetzt wird, ist die Änderung dramatisch. Um dies zu lösen, wird ein systemdSkript benötigt. Erstellen Sie die Datei /lib/systemd/system-sleep/display-auto-brightnessmit:

#!/bin/sh

# NAME: display-auto-brightness
# PATH: /lib/systemd/system-sleep/
# DESC: Restart display brightness when resuming from suspend
# CALL: Automatically called when system goes to sleep and wakes up
# DATE: August 2017. Modified: June 10, 2018.

# NOTE: Gives instant display brightness adjustment instead of waiting 1 to 59 seconds.

logger -t "logger -t "test" "\$0=$0, \$1=$1, \$2=$2" test" "\$0=$0, \$1=$1, \$2=$2"

case $1/$2 in
  pre/*)
    echo "/lib/systemd/system-sleep/display-auto-brightness: Going to $2..."
    ;;
  post/*)
    # March 28, 2018 On AW17R3 this script runs too fast
    sleep 2

    echo "/lib/systemd/system-sleep/display-auto-brightness: Resuming from $2..."

    # Find running tree processes containing "display-auto" AND "sleep"
    ProgramTree=$(pstree -g -p | grep display-auto | grep sleep)
    # echo's below will print in /var/log/syslog. Comment out with # to suppress
    echo "pstree -g -p | grep display-auto | grep sleep"
    echo "============================================="
    echo "$ProgramTree"

    # extract sleep program ID within `pstree`. eg we would want "16621" below:
    # |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(16621,1308)
    pID=$(echo "$ProgramTree" | cut -f 6 -d '(' )
    pID=$(echo "$pID" | cut -f1 -d",")

    kill $pID  # kill sleep command forcing screen brightness to adjust immediately
    rm /tmp/display-current-brightness
    echo "display-auto-brightness: sleep pID: '$pID' has been killed."
    ;;
esac

Markieren Sie die Datei als ausführbar mit:

chmod a+x /lib/systemd/system-sleep/display-auto-brightness

Zusammenfassung

Die aktuelle Helligkeit der Anzeige ist Systray

Zusätzlich zu dem zuvor vorgestellten Conky-Beispiel, Indikator-Systemmonitor , können Sie die aktuelle Helligkeit im System durch Bash anzeigen:

Display-Auto-Helligkeit-System

In diesem Systray-Beispiel wird die Helligkeit auf 418ungefähr 20 Minuten vor Sonnenuntergang eingestellt. Bei Sonnenuntergang beträgt der Wert 250 und die Tageshelligkeit 1200. Auf diesem Computer ist intel_backlight = 4882 möglich. Wenn Sie sich jedoch in Innenräumen mit geöffneten Vorhängen befinden, ist der Bildschirm wie ein Blick in die Sonne.

Die Systray-Anzeige wird mit folgendem Code eingerichtet:

#!/bin/bash

if [ -f ~/.lock-screen-timer-remaining ]; then
    text-spinner
    Spinner=$(cat ~/.last-text-spinner) # read last text spinner used
    Minutes=$(cat ~/.lock-screen-timer-remaining)
    systray=" $Spinner Lock screen in: $Minutes"
else
    systray=" Lock screen: OFF"
fi

if [ -f /tmp/display-current-brightness ]; then
    Brightness=$(cat /tmp/display-current-brightness)
    systray="$systray Brightness: $Brightness"
else
    systray="$systray Brightness: OFF"
fi

echo "$systray" # sysmon-indidicator will put echo string into systray for us.

exit 0

Diese Fragen und Antworten ( Kann BASH in Systray als Anwendungsindikator angezeigt werden? ) Beschreiben, wie der Indikator-Systemmonitor eingerichtet wird.

Zukünftige Verbesserungen

  • Migrieren von Bash-Skripten für diese Antwort auf Github
  • Unterstützung für externe Monitore mithilfe von hinzufügen xrandr
  • Hinzufügen von Unterstützung für mehr Rot / weniger Blau mit xrandr

Toller Beitrag, aber könnten Sie mir helfen, wie ich auf den Bildschirm komme, um den Übergang usw. zu konfigurieren?
MU

@MU Danke für deinen freundlichen Kommentar. Ich bin gerade dabei, das Dokument mit den vor einigen Monaten geschriebenen Änderungen zum Anhalten / Fortsetzen zu überarbeiten. Außerdem werde ich bald WSL-Hybridcode (Windows Subsystem für Linux) schreiben. Ich möchte Ihre Bedenken auch in das neue Dokument aufnehmen. Haben Sie Probleme beim Erstellen des /usr/local/bin/auto-brightness-configSkripts? Haben Sie Probleme beim Identifizieren des /sys/class/backlight/??????/brightnessTreibernamens? Ich möchte dies zu einem großartigen Dienstprogramm machen, und Ihre Frage ist wichtig.
WinEunuuchs2Unix

Ich habe nur keine Ahnung, basierend auf Ihrem Beitrag, wie Sie die Anzeige Auto Brithness Konfiguration
MU

@MU Kopieren Sie den obigen Code für /usr/local/bin/auto-brightness-configin Ihr /usr/local/binVerzeichnis in einer Datei mit dem Namen auto-brightness-config. Markieren Sie dann vom Terminal aus die ausführbare Datei mit chmod a+x /usr/local/bin/auto-brightness-config. Führen Sie dann das Skript vom Terminal aus durch Tippen aus /usr/local/bin/auto-brightness-config. Sie können eine Desktop-Verknüpfung zum Skript einrichten, um zu vermeiden, dass ein Terminal geöffnet und der Skriptname eingegeben wird.
WinEunuuchs2Unix

1
@dessert Ich habe endlich eine Github-Seite für eyesomedie nächste Inkarnation eingerichtet von display-auto-brightness: github.com/WinEunuuchs2Unix/eyesome Sie wird in den nächsten Wochen regelmäßig mit Dokumentation und Verbesserungen der Benutzeroberfläche aktualisiert.
WinEunuuchs2Unix

3

Ich habe gerade ein Programm geschrieben, das fast das tut, wonach Sie suchen. Es ändert die Helligkeit des Bildschirms basierend auf den von Ihrer Webcam aufgenommenen Bildern, um die umgebende Helligkeit zu erhalten. Sie können das Intervall zur Erkennung der Helligkeit und der Dimmgeschwindigkeit selbst auswählen.

https://github.com/Wandersalamander/Dimmer


1
Klingt nach einer großartigen Idee für die meisten Menschen - außer für diejenigen von uns, die Klebeband über der Webcam haben ...
WinEunuuchs2Unix

1
@ WinEunuuchs2Unix Auch für die "Betroffenen" mit Klebeband über der Kamera kann es toll sein! Sie müssen die Webcam nicht mit schwarzem Klebeband abdecken, um die Aufnahmen unbrauchbar zu machen. Ein weißes Blatt Papier erzielt fast den gleichen Anonymitätseffekt und behält dennoch die Fähigkeit der Kamera, die Helligkeit des Raums zu messen. Tatsächlich könnte das Blatt Papier es tatsächlich verbessern, da es die Lichtmenge, die tatsächlich auf die Kamera trifft, gleichmäßiger messen würde. Dieser Ton entspricht in etwa der Menge, die auf den Bildschirm trifft, wenn sich die Kamera direkt darüber befindet. =)
Vinícius M


0

Wenn Sie keinen Internetzugang haben, können Sie hdate verwenden:

hdate -s -l N50 -L E14 -z2

Ausgabe:

Wednesday, 26 June 2019, 23 Sivan 5779

sunrise: 04:55

sunset: 21:17

-s Sonnenuntergang Sonnenaufgang

-l -L Höhe und Breite von Prag (50 ° 05'N 14 ° 25'E)

-z Zone SELC = + 2

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.