kasse/0000755000175000017510000000000012563460206011374 5ustar jonnypeoplekasse/templates/0000755000175000017510000000000012563460053013372 5ustar jonnypeoplekasse/templates/login.html0000644000175000017510000000036512505101672015367 0ustar jonnypeople{% extends "layout.html" %} {% block content%}
{{ form.csrf_token }} {{ with_errors(form.username) }}
{{ with_errors(form.password) }}
{% endblock %} kasse/templates/gave.html0000644000175000017510000000050612505101672015176 0ustar jonnypeople{% extends "layout.html" %} {% block content %}

Geld abgeben

{{ form.csrf_token }} {{ with_errors(form.amount) }}
{{ with_errors(form.user) }}
{{ with_errors(form.comment) }}
{% endblock %} kasse/templates/layout.html0000644000175000017510000000141412505101672015570 0ustar jonnypeople {% macro with_errors(field) %} {% if field.label %}{{ field.label }}: {%endif%} {% if field.errors %} {% set css_class = 'has_error ' + kwargs.pop('class', '') %} {{ field(class=css_class, **kwargs) }} {% else %} {{ field(**kwargs) }} {% endif %} {% endmacro %} {% macro payment(p) %} {% endmacro%} kasse {% for msg in get_flashed_messages() %}
{{ msg }}
{% endfor %} {% block content%} {% endblock %} kasse/templates/user.html0000644000175000017510000000106412505101672015232 0ustar jonnypeople{% extends "layout.html" %} {% block content %}

{{ u.login }}

+

{%for p in u.sent_payments%}
{{ eur(p.cents) }} {% if p.comment %} {{ p.comment }} {% endif %}
{%endfor%}

-

{%for p in u.sent_payments%}
{{ eur(p.cents) }} {% if p.comment %} {{ p.comment }} {% endif %}
{%endfor%}
{% if own_page %}

Passwort

{% endif %} {% endblock %} kasse/templates/api.html0000644000175000017510000000056612505101672015033 0ustar jonnypeople{% extends "layout.html" %} {% block content %}
{{ with_errors(form.user) }}
{{ with_errors(form.password) }}
{{ with_errors(form.sender) }}
{{ with_errors(form.receiver) }}
{{ with_errors(form.amount) }}
{{ with_errors(form.comment) }}
{% endblock %} kasse/templates/status.html0000644000175000017510000000146012505101672015577 0ustar jonnypeople{% extends "layout.html" %} {% block content %}

Übersicht für {{ u.login }}

Aktueller Stand: {{ eur(balance) }}

++ Auslagen ++

{% for p in u.sent_payments[-1:-4:-1]%}
{{ eur(p.cents) }} {% if p.comment %} {{ p.comment }} {% endif %}
{% endfor%}

-- Schulden --

{% for p in u.received_payments[-1:-4:-1]%}
{{ eur(p.cents) }} {% if p.comment %} {{ p.comment }} {% endif %}
{% endfor%}

Aktionen

{{ form.csrf_token }} // Einkauf Ausgelegt // Geld abgegeben // Geld bekommen
{% endblock %} kasse/templates/got.html0000644000175000017510000000047612505101672015053 0ustar jonnypeople{% extends "layout.html" %} {% block content %}

Geld bekommen

{{ form.csrf_token }} {{ with_errors(form.amount) }}
{{ with_errors(form.user) }}
{{ with_errors(form.comment) }}
{% endblock %} kasse/templates/purchase.html0000644000175000017510000000046012505101672016065 0ustar jonnypeople{% extends "layout.html" %} {% block content %}

Einkauf

{{form.csrf_token}} {{with_errors(form.users)}}
{{with_errors(form.amount)}}
{{with_errors(form.comment)}}
{% endblock %} kasse/static/0000755000175000017510000000000012505101712012651 5ustar jonnypeoplekasse/static/style.css0000644000175000017510000000011312505101712014516 0ustar jonnypeople.recv { color: red; } .sent { color: green; } form { display: inline; } kasse/.git/0000755000175000017510000000000012505101677012235 5ustar jonnypeoplekasse/.git/description0000644000175000017510000000011112505101676014473 0ustar jonnypeopleUnnamed repository; edit this file 'description' to name the repository. kasse/.git/branches/0000755000175000017510000000000012505101674014017 5ustar jonnypeoplekasse/.git/HEAD0000644000175000017510000000002712505101676012657 0ustar jonnypeopleref: refs/heads/master kasse/.git/logs/0000755000175000017510000000000012505101677013201 5ustar jonnypeoplekasse/.git/logs/HEAD0000644000175000017510000000121612505101677013625 0ustar jonnypeople0000000000000000000000000000000000000000 a0641ff27057d66e6e4ada45353f5cb73e170b23 Jonathan Krebs 1420935259 +0100 commit (initial): init a0641ff27057d66e6e4ada45353f5cb73e170b23 a5d0f6aeb04e148952740ac30cb6315ab55b1b88 Jonathan Krebs 1420973474 +0100 commit: Einkaeufe a5d0f6aeb04e148952740ac30cb6315ab55b1b88 3e77d4d3f4b7131903bb32c109ed652bae4b5988 Jonathan Krebs 1420976202 +0100 commit: flask_login + sqlalchemy ist soo strange 3e77d4d3f4b7131903bb32c109ed652bae4b5988 bb09877fd5efc95983d392b94f059ffb1e1e72db Jonathan Krebs 1427407730 +0100 commit: foo kasse/.git/logs/refs/0000755000175000017510000000000012505101677014140 5ustar jonnypeoplekasse/.git/logs/refs/heads/0000755000175000017510000000000012505101677015224 5ustar jonnypeoplekasse/.git/logs/refs/heads/master0000644000175000017510000000121612505101677016442 0ustar jonnypeople0000000000000000000000000000000000000000 a0641ff27057d66e6e4ada45353f5cb73e170b23 Jonathan Krebs 1420935259 +0100 commit (initial): init a0641ff27057d66e6e4ada45353f5cb73e170b23 a5d0f6aeb04e148952740ac30cb6315ab55b1b88 Jonathan Krebs 1420973474 +0100 commit: Einkaeufe a5d0f6aeb04e148952740ac30cb6315ab55b1b88 3e77d4d3f4b7131903bb32c109ed652bae4b5988 Jonathan Krebs 1420976202 +0100 commit: flask_login + sqlalchemy ist soo strange 3e77d4d3f4b7131903bb32c109ed652bae4b5988 bb09877fd5efc95983d392b94f059ffb1e1e72db Jonathan Krebs 1427407730 +0100 commit: foo kasse/.git/config0000744000175000017510000000013412505101676013423 0ustar jonnypeople[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true kasse/.git/hooks/0000755000175000017510000000000012505101676013357 5ustar jonnypeoplekasse/.git/hooks/prepare-commit-msg.sample0000755000175000017510000000232712505101675020300 0ustar jonnypeople#!/bin/sh # # An example hook script to prepare the commit log message. # Called by "git commit" with the name of the file that has the # commit message, followed by the description of the commit # message's source. The hook's purpose is to edit the commit # message file. If the hook fails with a non-zero status, # the commit is aborted. # # To enable this hook, rename this file to "prepare-commit-msg". # This hook includes three examples. The first comments out the # "Conflicts:" part of a merge commit. # # The second includes the output of "git diff --name-status -r" # into the message, just before the "git status" output. It is # commented because it doesn't cope with --amend or with squashed # commits. # # The third example adds a Signed-off-by line to the message, that can # still be edited. This is rarely a good idea. case "$2,$3" in merge,) /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; # ,|template,) # /usr/bin/perl -i.bak -pe ' # print "\n" . `git diff --cached --name-status -r` # if /^#/ && $first++ == 0' "$1" ;; *) ;; esac # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" kasse/.git/hooks/update.sample0000755000175000017510000000703312505101676016052 0ustar jonnypeople#!/bin/sh # # An example hook script to blocks unannotated tags from entering. # Called by "git receive-pack" with arguments: refname sha1-old sha1-new # # To enable this hook, rename this file to "update". # # Config # ------ # hooks.allowunannotated # This boolean sets whether unannotated tags will be allowed into the # repository. By default they won't be. # hooks.allowdeletetag # This boolean sets whether deleting tags will be allowed in the # repository. By default they won't be. # hooks.allowmodifytag # This boolean sets whether a tag may be modified after creation. By default # it won't be. # hooks.allowdeletebranch # This boolean sets whether deleting branches will be allowed in the # repository. By default they won't be. # hooks.denycreatebranch # This boolean sets whether remotely creating branches will be denied # in the repository. By default this is allowed. # # --- Command line refname="$1" oldrev="$2" newrev="$3" # --- Safety check if [ -z "$GIT_DIR" ]; then echo "Don't run this script from the command line." >&2 echo " (if you want, you could supply GIT_DIR then run" >&2 echo " $0 )" >&2 exit 1 fi if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then echo "usage: $0 " >&2 exit 1 fi # --- Config allowunannotated=$(git config --bool hooks.allowunannotated) allowdeletebranch=$(git config --bool hooks.allowdeletebranch) denycreatebranch=$(git config --bool hooks.denycreatebranch) allowdeletetag=$(git config --bool hooks.allowdeletetag) allowmodifytag=$(git config --bool hooks.allowmodifytag) # check for no description projectdesc=$(sed -e '1q' "$GIT_DIR/description") case "$projectdesc" in "Unnamed repository"* | "") echo "*** Project description file hasn't been set" >&2 exit 1 ;; esac # --- Check types # if $newrev is 0000...0000, it's a commit to delete a ref. zero="0000000000000000000000000000000000000000" if [ "$newrev" = "$zero" ]; then newrev_type=delete else newrev_type=$(git cat-file -t $newrev) fi case "$refname","$newrev_type" in refs/tags/*,commit) # un-annotated tag short_refname=${refname##refs/tags/} if [ "$allowunannotated" != "true" ]; then echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 exit 1 fi ;; refs/tags/*,delete) # delete tag if [ "$allowdeletetag" != "true" ]; then echo "*** Deleting a tag is not allowed in this repository" >&2 exit 1 fi ;; refs/tags/*,tag) # annotated tag if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 then echo "*** Tag '$refname' already exists." >&2 echo "*** Modifying a tag is not allowed in this repository." >&2 exit 1 fi ;; refs/heads/*,commit) # branch if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then echo "*** Creating a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/heads/*,delete) # delete branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/remotes/*,commit) # tracking branch ;; refs/remotes/*,delete) # delete tracking branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a tracking branch is not allowed in this repository" >&2 exit 1 fi ;; *) # Anything else (is there anything else?) echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 exit 1 ;; esac # --- Finished exit 0 kasse/.git/hooks/pre-push.sample0000755000175000017510000000251012505101675016325 0ustar jonnypeople#!/bin/sh # An example hook script to verify what is about to be pushed. Called by "git # push" after it has checked the remote status, but before anything has been # pushed. If this script exits with a non-zero status nothing will be pushed. # # This hook is called with the following parameters: # # $1 -- Name of the remote to which the push is being done # $2 -- URL to which the push is being done # # If pushing without using a named remote those arguments will be equal. # # Information about the commits which are being pushed is supplied as lines to # the standard input in the form: # # # # This sample shows how to prevent push of commits where the log message starts # with "WIP" (work in progress). remote="$1" url="$2" z40=0000000000000000000000000000000000000000 IFS=' ' while read local_ref local_sha remote_ref remote_sha do if [ "$local_sha" = $z40 ] then # Handle delete : else if [ "$remote_sha" = $z40 ] then # New branch, examine all commits range="$local_sha" else # Update to existing branch, examine new commits range="$remote_sha..$local_sha" fi # Check for WIP commit commit=`git rev-list -n 1 --grep '^WIP' "$range"` if [ -n "$commit" ] then echo "Found WIP commit in $local_ref, not pushing" exit 1 fi fi done exit 0 kasse/.git/hooks/applypatch-msg.sample0000755000175000017510000000070412505101676017517 0ustar jonnypeople#!/bin/sh # # An example hook script to check the commit log message taken by # applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. The hook is # allowed to edit the commit message file. # # To enable this hook, rename this file to "applypatch-msg". . git-sh-setup test -x "$GIT_DIR/hooks/commit-msg" && exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} : kasse/.git/hooks/pre-rebase.sample0000755000175000017510000001144212505101676016614 0ustar jonnypeople#!/bin/sh # # Copyright (c) 2006, 2008 Junio C Hamano # # The "pre-rebase" hook is run just before "git rebase" starts doing # its job, and can prevent the command from running by exiting with # non-zero status. # # The hook is called with the following parameters: # # $1 -- the upstream the series was forked from. # $2 -- the branch being rebased (or empty when rebasing the current branch). # # This sample shows how to prevent topic branches that are already # merged to 'next' branch from getting rebased, because allowing it # would result in rebasing already published history. publish=next basebranch="$1" if test "$#" = 2 then topic="refs/heads/$2" else topic=`git symbolic-ref HEAD` || exit 0 ;# we do not interrupt rebasing detached HEAD fi case "$topic" in refs/heads/??/*) ;; *) exit 0 ;# we do not interrupt others. ;; esac # Now we are dealing with a topic branch being rebased # on top of master. Is it OK to rebase it? # Does the topic really exist? git show-ref -q "$topic" || { echo >&2 "No such branch $topic" exit 1 } # Is topic fully merged to master? not_in_master=`git rev-list --pretty=oneline ^master "$topic"` if test -z "$not_in_master" then echo >&2 "$topic is fully merged to master; better remove it." exit 1 ;# we could allow it, but there is no point. fi # Is topic ever merged to next? If so you should not be rebasing it. only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` only_next_2=`git rev-list ^master ${publish} | sort` if test "$only_next_1" = "$only_next_2" then not_in_topic=`git rev-list "^$topic" master` if test -z "$not_in_topic" then echo >&2 "$topic is already up-to-date with master" exit 1 ;# we could allow it, but there is no point. else exit 0 fi else not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` /usr/bin/perl -e ' my $topic = $ARGV[0]; my $msg = "* $topic has commits already merged to public branch:\n"; my (%not_in_next) = map { /^([0-9a-f]+) /; ($1 => 1); } split(/\n/, $ARGV[1]); for my $elem (map { /^([0-9a-f]+) (.*)$/; [$1 => $2]; } split(/\n/, $ARGV[2])) { if (!exists $not_in_next{$elem->[0]}) { if ($msg) { print STDERR $msg; undef $msg; } print STDERR " $elem->[1]\n"; } } ' "$topic" "$not_in_next" "$not_in_master" exit 1 fi <<\DOC_END This sample hook safeguards topic branches that have been published from being rewound. The workflow assumed here is: * Once a topic branch forks from "master", "master" is never merged into it again (either directly or indirectly). * Once a topic branch is fully cooked and merged into "master", it is deleted. If you need to build on top of it to correct earlier mistakes, a new topic branch is created by forking at the tip of the "master". This is not strictly necessary, but it makes it easier to keep your history simple. * Whenever you need to test or publish your changes to topic branches, merge them into "next" branch. The script, being an example, hardcodes the publish branch name to be "next", but it is trivial to make it configurable via $GIT_DIR/config mechanism. With this workflow, you would want to know: (1) ... if a topic branch has ever been merged to "next". Young topic branches can have stupid mistakes you would rather clean up before publishing, and things that have not been merged into other branches can be easily rebased without affecting other people. But once it is published, you would not want to rewind it. (2) ... if a topic branch has been fully merged to "master". Then you can delete it. More importantly, you should not build on top of it -- other people may already want to change things related to the topic as patches against your "master", so if you need further changes, it is better to fork the topic (perhaps with the same name) afresh from the tip of "master". Let's look at this example: o---o---o---o---o---o---o---o---o---o "next" / / / / / a---a---b A / / / / / / / / c---c---c---c B / / / / \ / / / / b---b C \ / / / / / \ / ---o---o---o---o---o---o---o---o---o---o---o "master" A, B and C are topic branches. * A has one fix since it was merged up to "next". * B has finished. It has been fully merged up to "master" and "next", and is ready to be deleted. * C has not merged to "next" at all. We would want to allow C to be rebased, refuse A, and encourage B to be deleted. To compute (1): git rev-list ^master ^topic next git rev-list ^master next if these match, topic has not merged in next at all. To compute (2): git rev-list master..topic if this is empty, it is fully merged to "master". DOC_END kasse/.git/hooks/commit-msg.sample0000755000175000017510000000160012505101675016635 0ustar jonnypeople#!/bin/sh # # An example hook script to check the commit log message. # Called by "git commit" with one argument, the name of the file # that has the commit message. The hook should exit with non-zero # status after issuing an appropriate message if it wants to stop the # commit. The hook is allowed to edit the commit message file. # # To enable this hook, rename this file to "commit-msg". # Uncomment the below to add a Signed-off-by line to the message. # Doing this in a hook is a bad idea in general, but the prepare-commit-msg # hook is more suited to it. # # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" # This example catches duplicate Signed-off-by lines. test "" = "$(grep '^Signed-off-by: ' "$1" | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { echo >&2 Duplicate Signed-off-by lines. exit 1 } kasse/.git/hooks/post-update.sample0000755000175000017510000000027512505101675017035 0ustar jonnypeople#!/bin/sh # # An example hook script to prepare a packed repository for use over # dumb transports. # # To enable this hook, rename this file to "post-update". exec git update-server-info kasse/.git/hooks/pre-applypatch.sample0000755000175000017510000000061612505101676017521 0ustar jonnypeople#!/bin/sh # # An example hook script to verify what is about to be committed # by applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. # # To enable this hook, rename this file to "pre-applypatch". . git-sh-setup test -x "$GIT_DIR/hooks/pre-commit" && exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} : kasse/.git/hooks/pre-commit.sample0000755000175000017510000000315212505101675016641 0ustar jonnypeople#!/bin/sh # # An example hook script to verify what is about to be committed. # Called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. # # To enable this hook, rename this file to "pre-commit". if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # If you want to allow non-ASCII filenames set this variable to true. allownonascii=$(git config --bool hooks.allownonascii) # Redirect output to stderr. exec 1>&2 # Cross platform projects tend to avoid non-ASCII filenames; prevent # them from being added to the repository. We exploit the fact that the # printable range starts at the space character and ends with tilde. if [ "$allownonascii" != "true" ] && # Note that the use of brackets around a tr range is ok here, (it's # even required, for portability to Solaris 10's /usr/bin/tr), since # the square bracket bytes happen to fall in the designated range. test $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 then cat <<\EOF Error: Attempt to add a non-ASCII file name. This can cause problems if you want to work with people on other platforms. To be portable it is advisable to rename the file. If you know what you are doing you can disable this check using: git config hooks.allownonascii true EOF exit 1 fi # If there are whitespace errors, print the offending file names and fail. exec git diff-index --check --cached $against -- kasse/.git/index0000644000175000017510000000335412505101675013272 0ustar jonnypeopleDIRCTTr p%oꘫZNj_b3hxapp.pyTT 0a/k4O#'Wa>scanner/.gentex.py.swpTrߙdTrC s TӵT|Mscanner/api.pyT/;+T/;+ +S;0D@sIBaqZscanner/api.pycT1~;T1~; >Th s;l Pٛާ3scanner/codes.auxT1DT1D edPڟ-}_tmscanner/codes.logT1DT1D @m.E~QY]Ascanner/codes.pdfT5|"{T5|!Ĩk '- O25-# scanner/codes.texTT Znp|A#{I%scanner/gentex.pyT6_s T5`  0<emRf]9scanner/scanner.pyT.'T.' _M[zz1g3_wscanner/scanner.pycTq&JTq- K)!eX *\TPstatic/style.cssT,6 T,n- v9=,8Q O4templates/api.htmlTW gTW * F:zR.^k.l+))templates/gave.htmlTW9V4TW9FL >Hbs3ab) Hhtemplates/got.htmlUe"Ue  x`u|cPz+*templates/layout.htmlTW7lTW7 e Pq'`\ޣHtemplates/login.htmlTU< TU 0QK-ϴ"templates/purchase.htmlTGTT KQ 0Uy͂B/X Bhatemplates/status.htmlUa$7Ua$7 4=|\F(templates/user.htmlTREE4-1 2 static1 0 (}=i="?|>Y-#w7mJ|=2aeS U]je)cc+sE(pz޿vܤw9B P(@ wU$oK(@ P(@ PT$r~ _{9CNcd[ȹٽv;(~{{8z'8Awa ,?wu6ɳl|FLG&ƢM"Νh"DAcTy0_n*TI[kpCn>Z~ G/$ φ~zXI@{5phPȚJZГ9=ʧ-D֚,3Ų={ز 3e(B3h/gp濙Bch)aI<ٖЙiMx Zb.cUؾ&RѱO{(TS9j?V.|I޾T縤vw=Iab3~j G|9:XB,=s 0΍ub5+Ʊ+&$8g(W@hL%T7 -](K ZS9>$?8ԽC ԸcM9Qp?P+BB3@)N9̕IVNͧx;< _dlTC5Ul4O\Mkasse/.git/objects/5d/0000755000175000017510000000000012505101701014162 5ustar jonnypeoplekasse/.git/objects/5d/4e7d0176a3574543fb02da50297a8052d348e50000444000175000017510000000064412505101701021013 0ustar jonnypeoplexURn0bj AUPO+ a/=!Cb 8m߱Dqg{ƭYZ|'_xMNS_ڍ ZX*lM% QD;5Mi“zPnjpt8e8z`%ƹXYEe-j 3itA&G2\3 !˜(n3-}b 2$#i3X8|e,kasse/.git/objects/46/0000755000175000017510000000000012505101705014107 5ustar jonnypeoplekasse/.git/objects/46/229e880db3dc30a0ed6315f539bf1bce1af6de0000444000175000017510000000366012505101706021534 0ustar jonnypeoplexXkD+ !nLYnB@D3ABQdUbJ=&Ϲ=ݰA'ZĮ}pn=SJllVay^Ycs&SJmad&R|: n5MVwk2YU{~[؈f~|įz1A y[jB3Utѩ&hUSIQiTEuIvkYr)=[zc7<jٌۛ=[ @-oହ[δ(0؂әU-&}`NlYѵ\Gx_\?ճO=8Hq~iS#սYqsQx`tV|sfPy-E1Ŕ~Ϫr x٬SKUvٕ^Q_ BܹPDO6-_ mm㵲bZ[|U p]ZӦy:Uh2բkl+ (v=vYoKmDk{s CעrJxx9@;M 2ax^5٧ "Y8ō,{oN<.BcT7޻JB?ܒY5QA p=k%\TҪʮQ,K!W]!Ω~,qCLm$.wvG;ݕ+sǒ`a7HjXݓjG2YAS\jg_gJu㝵m[&^8y*wv$a8|T3(Ǹ(&%|pPDz;zirV(&v>l2`,tXPP#e< }- [)Q ,bB)NRѮIY7)2x1GnD"_u& h$U*Isk6x7]M)QJ$I)DnNC"#0 .=&bk~Vw:vr;(Y4y5o]'(?d( P6uG@ xE%wd6"\U#$ݵ~טq;nwfMs|깁)s~lI:Ff r:%y4DqrzNE%2ZCD%' K@\6o>4o1 9=|">1pnH~6=>躏Rq꧋z./QzvRuoh5vH\91Fw`[eyĀ#]:PNT܁&8!9p/ؤʒubј3^$&;J=*JY.Q؉D+&m}IOn d{9BH;u]ukW/Ptj1w j yapJ|%3")y4Aiۤw>l`5~9~yy[\?r:;[0wSiKkQ9g^IKf$zQvI^f4*nlapJҘd *ܳa@v0#la<4ZPИJurBDVb])kasse/.git/objects/55/0000755000175000017510000000000012505101705014107 5ustar jonnypeoplekasse/.git/objects/55/7992cd82b4e3f242cc2f8e58bd0942689961fe0000444000175000017510000000066012505101705021220 0ustar jonnypeoplexSM05`]mBJ)ca鱅I`Y20 #'v̌{BMw?=SbO+wބ2i4A|ͶWZCubla ԭy3Z8y}`+%>4wfQfC]WRGuv'Sَ w" n(VWrC*#m)"ݶJ>Q[՟xƢKBE7"CvEI6A8I^rlQb;boׄjh#dj9z2&lUgJ=0#]{g=ƔmJg7Wy_MѷU(zbdA94*ʆ;\jOxYԨy_|>SI_pvAD -=6Xگm kasse/.git/objects/e5/0000755000175000017510000000000012505101703014165 5ustar jonnypeoplekasse/.git/objects/e5/fa163b304440ea9e73914992e542a561fc715a0000444000175000017510000000135712505101703021101 0ustar jonnypeoplexTkAϚ"(_IVr\xA S,7sI>Udngv~|hŸkZ ki(m^l>9';~n8?l~<ɲ_x| >޽~QAy܀/$}n&6cMwbgYnRwme㕄7,]|h4StH͠E!'?)j]}SdPHz|V w6ɏ|8VuOG(s(L`=N㈤6TU /EQ ئӜ?9e6"پJ)"qS*a$. [xVpsW@/%:mQ|HDk4{#@KhAqZyvJPM{0GA(S <"iWB8A$`ꪣJ̻| [aw\y2+bV6 "$,bO}Bzso/ا06/֮1Hl0s QpCbe܊xU ]$?L1T/n(E)$AW8Iء@5bkB] e ZΩRHA^>:}M5bpۖh\>xig0r(<Y/>8!fA:Egچ(r_)d"PrgHۿtB kasse/.git/objects/ac/0000755000175000017510000000000012505101711014236 5ustar jonnypeoplekasse/.git/objects/ac/ab4487a1914b6c65f155e57b615199f8f5c8b00000444000175000017510000000022312505101711021244 0ustar jonnypeoplex+)JMU046g040031QH,(+d?ɫč3^VBqrb^^jԝjLt}fbBU$d&3,[UfzZL((I-I,I-fx+FdC<>#?r:Xkasse/.git/objects/66/0000755000175000017510000000000012505101701014105 5ustar jonnypeoplekasse/.git/objects/66/d56400f0ee55d4a240c17e955f7999919ec8e60000444000175000017510000000025512505101701021134 0ustar jonnypeoplex+)JMU0d040031QHO,K(a#QyH/޼&Wr@Ԩ <_zI%R2Jd<_{\t,+ )ÕƳU+oHd۩kUU\XRZ Q&!_Pb'Dͻ Nkasse/.git/objects/d1/0000755000175000017510000000000012505101700014155 5ustar jonnypeoplekasse/.git/objects/d1/6f97e4ea98ab5a0f4e6a1f1b5f62173368e9780000444000175000017510000000627112505101700021344 0ustar jonnypeoplexZmsg ŠBxeX4帑V< /4vᅤtOaW Փ/O[].TyoUx2YU!x6m-XbSՍԪlLUl'A,~yrOSl([<0t,oR2 ]6J7na-i>-.2Y*~L2O(ڄ3ˑHқƀ/7,FN@}c4֯,e32wXC8l+O ݭ*KX6򎏎f mU2)adLڜHP\28%1s$x1DKۤeu7s*2rFi3?#Sn*E:,Fbc ŧ92S/tuH>dpM- 4pD jZb'Ւ (-^VTKخ\4gu]0x3JasO L$Ɓ8ql{e?)nK~EWI5$\5ᣣ#mjMRA"}+:Y Y~ @z >K.At ā0ƦHIġZ(si3>2nk(<;n/EuM)SG*EIZ쎵o¶)톁nՁ[?FVr> seX-{|86(k6f|Hnd\KA .#QotYL bb9u2eAQgIp'ʦT!ϡpƈ~s:װw4*.:JM@czk*p0╟TAƧ̪*Q޵(߶{;,޵\vuKؗX=@ J6軯I$(Y<>QgS#uD(Yt$R(]43P#vh'5 =fJL[ >Qm;^h$eM#9#z1'CQ3jfJ4K/v-2]\èJ<=01e1:-h6d6WW &*Hh CB ᑉ>xn5D{J2At])aޱ9qə*osڶȿ3q-' WSB'Nj}}KFƠwÞ},fN:;Zqj,H9n]~QH{0PB^$yR4QO6^Ox؊>pHo|eݠ[r>w{W3J[%%#: {S qoH2qZZ9nS868_&ԍaomDz{7>mcr-uyprEHqg ;h0bw8Uoxi|_WeIh*S^>^YHߥ=B-:tz8>_~T]Pz ԟĠpl9ˣ0_몃+t CeJ ]dw.{"V![fz넼iA)AEtc^4pShٙ@oOP:r5oL洱nRC FJvq:/mkasse/.git/objects/82/0000755000175000017510000000000012505101704014106 5ustar jonnypeoplekasse/.git/objects/82/96aa508f7105c127fb60135cdea3d6c848e1940000444000175000017510000000027612505101704021164 0ustar jonnypeoplexe 0Eگݴ k%iSdJ2A鿛֍r՘|e j-:&dƻ O+8ew퍰it,HYn6Pma e@@Aa1xpx\"TITDV^kasse/.git/objects/a4/0000755000175000017510000000000012505101701014156 5ustar jonnypeoplekasse/.git/objects/a4/fdee0b1d8c85283ca34930b0a9c08d13a138900000444000175000017510000000006612505101701021274 0ustar jonnypeoplex+)JMU06g040031Q(.IK..fx~j3Z$ 8Vkasse/.git/objects/30/0000755000175000017510000000000012505101707014102 5ustar jonnypeoplekasse/.git/objects/30/e36b60f6280c005bb561225db78a111c4d39540000444000175000017510000000474312505101707021000 0ustar jonnypeoplexY[s3ŠB ;fb5ndgx0K`I ~g/t|9gUQ؟:~iJVl꒥1ida;%+Ufd]yumx8m">7b\uvG}l+}˧M67pY_xd-Ek{:pA;^ȜZY8z'w}{NLwf6{kd1n8M+^B[s:"S¤bZ'U^9%Y]_\+}^HÃ@{ I#.N3m|K*kY(N(7`pi7&-y7B`]$/\WM<B$&C2@O-TZ<j~X9ZiTf Ѫ).##mHP+/EeZx?TF>GZzx|BA`!7ՏbG"uQ% NGo.Hham@zߊg Ϥ;'F"YнdP>oȄ?_L@ݙ˓A$-[N;K19Fcu:y\o[T!vSH!7@@7;b%`6H nkwDx8ֆ߉N8vOZo!nr딄&0GJnٶXX)5F?m"DBVú˗C%h{cßþ4/X/sRG{igmt>Jvnr葱aFt\5F=BygF=3V"n;nN)˴aoJ.ö/h젽|CGtb\ : Cٻ J/s~9  YSڗMS(8 a)sd`z ͱ~֝ffݔ1vwEQhLt[0gR nWUFfdz1^?Op1ٕ#TNiaӽsi{'*LM4SC[o}0AL/7 ~YinLVPCD\Q=%EE["*.$m2Kbl-9~kOȑ=&h8Dڷ;VFx]a,6S[[;Avٷ`/UU>uJN/GؗۿG/ӚG? h:!oGdu;§%#:~#YA"h Z_ E'䧈@(t6>:&kasse/.git/objects/30/3c891165c16decbd5266a2fe1fc65d81131a390000444000175000017510000000110512505101707021224 0ustar jonnypeoplexTn0Y_A)l%h5Hs arSkJj]kƄԂdz3q/tLZkcBNrL-4+EKi3?BCV7NO4X<@ Unä\ &)މ 'xB{#὜@ 9޽xrEVY>܃OpިFN+( Y$4)c, c-q4:7K~'fkasse/.git/objects/78/0000755000175000017510000000000012505101704014113 5ustar jonnypeoplekasse/.git/objects/78/6075b0c87cf389639fc408507ae6f31d2b192a0000444000175000017510000000070512505101704021116 0ustar jonnypeoplexURM0Y$݄ZUKs{'d`VA[;T9̼q>~N<}`twiTf݈'IVr8~_.L3)76hlm'h:cU:vj[ZTe/`>%Cӫw=LD&OaBQ|@&˼yh_!σFYD-acq7;-A(A2UCy(=sg@M\(3-}!zg)Nh\q4.epieE keN`QW)U#..XJa8T)<[ݰ"''8Ai4rŠ!^p~|Eyܯ^LtQ5fB"yD*ѫ߷Sp{ZmQu=渽swn6&n{@Q L4kasse/.git/objects/info/0000755000175000017510000000000012505101706014612 5ustar jonnypeoplekasse/.git/objects/9c/0000755000175000017510000000000012505101702014166 5ustar jonnypeoplekasse/.git/objects/9c/6d2e02cec7fb457eef515911de07b15de841af0000444000175000017510000003773112505101702021551 0ustar jonnypeoplexp/ѳ.';wlb۶m۶c;ٱm۶m/sϩwojfjꯧV-o @¢:hšUh&;CKhnnhzi[3gsFV:E-M E MMMyyM l׫tdb uԸI"U9xG"L Qjrhi`x8޿˴ $ҕ:?( }mLLпlHVUN~9AWL}9޿"80cM;8|>,ΰ~|[6 $Z3+\ލ>!0FѨF!*0} ZfR=~|FSqYCӪIkޜ/ُF׽0)xd4$"RxF)7Qx^?YX hp6^7 kݺ% % -ΪPea±`?scq'KEK™DAb,۰ S9 1dBT.O XrZJ%sZw"5)LX[3煕`VF"Ѿ#5$Y- EK‹" \&='4oK*78b6Vcd?;g+EGEC݅3ҰrSpڨVTb69O>P7r!)__V ,>a+2$u8=MWhXRSUY mimgsyyy(L])<+"ku;E)!Ix}.s.I=FwD8JOqnu!oN |R0kdV!FXb.c].6Q>ܠuyQVn2XEƚTb.15c0*.$dZdN%Ys{Jݒ]yb!™U ;e? G%?d TVTOa;v.U{:7Zj} n^%ʨ#]L G䫑 lmp `|\SCQS;gP(03MH zEȀkYWEBWEJ3 {ki $4MI( !BКGtuFaK FkVE*S0luHl:.( Lp3]",BBD)1ySC{*U >`qTPu#~ܡ,-˃06yoZ̕CahF{r!6Eh DJU,lׯҁ.f5noމLdA_t?*ZdzE: au2MGaTlL뒾 .%fD5Ҳl<@ZMT3 em70\gO Idio(_>~>ئ!r,.]?rZu2Ҿ I *]<fbc#y1ki%hþfGCq3†y(YlR4D6"0rceed* F65Ĭuڊ<b74=jz10)rzHEpw%d Do3#'\ o < 4#6~j^/jUBp.G[U{4ӁW0Cљ^5*ߖah\"H]V;\#z_|[#9Es_ '\>!4ɋXG@}R#m[tG \bGȽ̪2[+Wv?.eѸ0""YMn$Io0"ّ[bLD:F"W޷0(50p2Tr{l[hb\+^+I_Ծ4"O2j}$okSUW}{ھyε-* 5LcƬVب }4D_v9%8Л3ZY0GTpɺd7;DY`%Fxy@' #T>JK@2DeІBW.>|&OITšPx0@*wDs(-K8NsL_ؐoہ~4fF/Fi[4MI'DvKt˯ RX8⍊,[Ն;1Q[3I៸p$A-^1a#hq8A{ \i`lHe/O6ST;k)Oљ *\}A mI!@-V2CnUuh!֫ fGA: v 3,0@ms+؋1qžĜ'Z, oN鬻:?\Aq('@ѝzb 9<ԠӾ ge'ʁ D?[Ӈ52x\YtGLSx/5;>3+>FV蟰DIϒ|[ɠMl;-)'g?R{}Fğ L l?1Y,ARBn?G &a+/0kY@[ 7Ϙ3jiz$gaiH8`?$ pmm-S]m-w8E4$η 5,ODZ{%?++5>5> LHȳW k"i`Xg{N}ާ\=|vt]q+Eԉ%gVoz B]EO&FVlɃV6R7K+T±qIm0]'@K,Ntp_ߝ(\Ύ^V)c-7G|㧉TWyǒp9>,#B8(3 )FQ3injb@=Q,ZӪGݲY}ޕaHr GJ 7kD1qÍ3)pQ lt'()X\Fj-Xb \Cv6 ~= q.U>x8Y~ ۡ-plO tdcueC)~{% ;߃aS8=k.pH:x}I9@|fCZ1W=64x[J$F3dl:]˵U-27wJk&g8do)Dtgn! 3;=WvTMFTs`x߾ MJQ)oXVWKJ#u 4 Bʒ[v=ƌ(eNK䚚Njf݃Tnysvdeml?R=VX; myʿ~A |eb|_^f>@`6 deny 2iwBG8atܬQ;>gvIШ='`(#.xyxr3V(a#rmVC  YPQ%Yo>!M~@NaY߾׉EuLQ[1UBcђ,-ӡc\vZ3!@3+Q'!Wd__ 8)aϬ 1Rrb"t8qs7٧3_^#7krn@FF22 nw_+RxrhR+\X"ƾՋ)|fl; yYX+e=8 m$IV%UUog-U,%Kr `4VGϑk4hu׼VNn]nk/-|.G)GwXE~if.q^syJa Vjc<_ҽ:+7\YĶ{&b %+{qL^JNs3PxDREՂ7wy}:eZxF]v'6$[/w1Uf ZF;9^MmgN%:DH-ب+ŒS^l!o"6ƻoVp*pCM 4.[>(ݢ/$0/yC*@uP9 iJAIwŜR@r᜾m:OcgfZX EVp4Djܜ7(9pԥz^ \2R͝SyGsE*Jh{4(3SzS5rրƐ@)d\/.z\䅛GseWt? >Yi9|'Sq,,/D ?2rg1t`-:) %zP?Tm)~.ǯ'Ƽg5 }4f'΅C7zX`L 'Kƒpq}:r웠^ʲ4K^zEuI 7;c˺o3Gy;Ϊ ' ̈,{Ob>lvy\+RInď3#v+CKTnjMeBvT(ą +q`^ҜնԹ-Zf4*[;쪪eGm:GxFfG=[Y6`S,*N4o~#RN}Ewhz۷=Y~8 7aݸ"uC=G|͓.Blr \݋4)2fpq!0TaڈyW<}/L~$͕>5t)>BM=|Ot'Xd.>͇7&ġ@^ HK͚K|3m!څ︮e5UMh@ZQ雵&o YF{1V2; eTOpJGl='nVrԷVXI GӟIM*U4IYB H2 |[z3cFzU1rQ-&H[U|D߱F~&J{e6XH~5݇#jՙ#pu;H&ڇt!ΔawFy |m'w2.;VAyjdTaʠtg*pY̩R4nZ'9?^ɭ+jP3(aa>nkԝj̹ѐ~ͽx3F_λSFg/ʒ] zL6oD$I!*y$4Fz-Xn%' tymF1R/bJ2R8&"xX} ڨUMk\U wY "k Y"OPTQ}O5k(յb{<`Fw"$#n8K)KfU_{*Լ;/0y()p`pmsBθ[Br稅kSzPQLkidn1#HkUX1f+M)P~{MekQ`>eo,>ZY'F{"Bml!}g׻6gycJp.)0TΎ+s$bvץyw.L( g_/ٜD^m q5' 1$UKMHe=lů[V# Ъ?F$:gTa#wcC0/VFKQ.(HOU{GyeQM>V[ ޟ,3{j0_Gx6O0c)%Jيfʬ$st{x?]/(Ș1Dav(W"G&l%Fo-uF Y˟H-]֖w4 ϳ+]|D+Tc?7eKvqєM%]i^~&)^ Yb+E1\o{} %Y21'U6Ҍ-7xqT)Y t=o\N^>$^)o N9K-1Cg'9e,dP?) nv}(֫g佈uֳYH)%^nj@^Ul5`<6mHBTπA)B)g,(fU#N_xF<<p$Oɩ8p%CMNz&S.αN3C/v髨 |hxTtv\q%_7z~Q@-3sH(Ɋ;Fxm0T5F__]-,+["O,~i :­!:<< .רy5Ə-۵x!6Q9fLq]bI̮ҿ'|DCy%H._[],K(/|fy!qGFhV88`AQʝ½MTdlqz DI?%]4& -rx \v\׏z1W=X'[> -)S_?Y4 &fQ{tCg'I#DĴކ v(- l/GfM`\xoYл[ ɜ)R{D [+e 34,Ĝ勊l 4N˾gE2pHbzMLV54P)&4.W5G1vϖyI/V)0|7w57Qݒ^̵o~2,OCQ -Ii$amTDiy[nDLZMD< MM2)9F{'3݀mю|f3>z88WV* 힪,~yE$BQjpLzٵQ ]U]*צ/j^DUsdҵ?,)'K$cFZp%&&c$-)Vbh!gHBʎFO&Dp{]UXT Uy'ʃϜr"Y1:q5D!P9Xˑ[t@EjQoX+ F$R W5Pzb@;A,n9./6)Mk΍7/D.\u>qro[Qٚ:h+< T5 raN/c-n1xr؆DY$BФx)O'|9ʻGW9$ԙ_ r͛L2[p*%V(x*Tyu)ǴtogڂuvWJOAũelٖ$X^uŌ7c)XzUN`(g6޿֝mNϝK.l0 ps=iLcV\G{/$i^}sa,PjLre`UB|;wcNg'S(FQ#ԼL0| ýfWS5f4-q^=8+y.RY*S6?K-魁pwf GNmvg+̓OSU} U-{oP/ I+Zd {{lwM K5_&e]jťlBb#-W㉨ çl鳗$->14F͑XK@EɡxS6ĩHA aC:1f>`%an}75?xjDt ޞzF -g/'L)Lxb^| &ŲofM,?%`?1o.چ)ճ"I7xpºF+h{*ፁΜh _1>:+uLp8?M}<*Jc2-Bot\b%Qڳy\&C S-I_;VgѻDis 0t+v6O [tK韡l̄ 70Dy3xsewS.}Ͱw@i ^?KɆD6bWB Jl&e:CŹ=[ָܚɄ$zJ}Q"-66QPN!BL)tfQHS@eJ(LG_w <^g]⩝#km|FY0AqշyS:*ARJ{f;1\hEvҁe~5ZX"j)@  y}EH|ULTMoYƨs`oF@I6#gS~P-nv& |A!{ߡE>h _Y{|_Ìt65Dz ON#^AzM'>+pгglMRG< eb[f5u#:o%fT-js2+[ٺ·#~qW#.Mb*}ZŒXi[I%Ԃ%R[ TV=Jsf53HtAZ4! wyrXYr]c5 ȏ4 GUZ?dI:H#u\DgKs,2Yƺ{ #ŤSRLF[$:Y@~ HH4ܩѬ/ ߓ!2iDd )B/ T l߾~?`Rf^I̙wR]amY/ņO-VT;L:d ӷT0^i 6j1YnS|wQCcL!| gi}b:6ÕĦau-HYqHv XCV?GNq%"6dLj ,7[\WWBvPu_)Q XpX$XrI/X|"7E40' ;sZ#'rd{dɐ.ʒ/5uUmzah@Eׂ90{VBSN ; 5k雥 oQ n"8բgCΒ}ٌ8$_ΗEu#,OK |sN^!1 mrޒڼka57_.F3*^u\*Iq-4bD#I7Y`\Vbʐ2x顡;ee8ת43umTزPtLs *}/ƾŪ3QgLӄt[v{i}w  ͧa;~Ɨi`¢#DU!>gh";I ,.&Y>ʇUe(X^uwAA>MgN7PU&DD;rfLqC8wX)it؄%4qrvx+U:I7RLR~ eEF5ٛ01:I>6W.0T@Nv4ʫCbN\,2}3#wOb,P{q"}9-Q%x)z{@KK:)*IKVؖ+IxgtTi+d4g6!z^RK{0|C ;;E"+n?뺣mj+]2*Kk%Ai*[&K#,e,}6 M#eȫQډs$}E74dqkcn0Zi "/|zK:BꦧqK{5 XL>4컛[@w컨]^8:>AΥ|p'Uox Ըx}:i";r|>ːNlzS< HV} e{<T]m6Ol zn\<鳍.0׼#6,@321hb M/aklN@`ҁW4)Aӫh~??uvv{M~h@-hq 2DX؄8XؘlB ^;KΏ~k23;5 ˟2 '@!~F _ôļY lV&FVhRR9Q< kasse/.git/objects/f5/0000755000175000017510000000000012505101707014172 5ustar jonnypeoplekasse/.git/objects/f5/7b499179f7bf2b51efdfde964c38fd101ada540000444000175000017510000000016612505101707021566 0ustar jonnypeoplex+)JMU040f040031QH,(+dpSɢ_-KvKK2}-Ӫa` -&@$3]Ma."uS+gNwm-kasse/.git/objects/64/0000755000175000017510000000000012505101706014110 5ustar jonnypeoplekasse/.git/objects/64/b3068c0d22236595290ea85e8c4830a30eff110000444000175000017510000000460612505101706021016 0ustar jonnypeoplexYYs3~x] ЅزL:b.%,bw4)9HUS@bwzz,f4}ىQd)NodMtezz>a8,^6j"' u<LHg6e-K.Rey$=rT0[/W^1f9c[$*eЍI.w ؂:U֭'ݏ(8n*ݹ5۾w\O3"v;cU&JYĖv 'M6*]U9@;'-:`1X6x?,TF ZOV1D;WO}zwta qSXPҦ4 ί˶mzh jeK _%l=})-uثR%vF7U 'YQĘ }z+]sF2yoEfG /yMveàj8 r~?jݩ gD W:$n`-5 kчa>#M%eXr UN׼Da2\#aXBm2j=e/{AGG{Z vZOpɵǽuOa{%z&(b33S*̠/O YYӻqXE=,B"5QpjdS(qCk Pu;|]VVC+;)WY2WtwH5 }=fTNvmo >[`o;8Mmn&'[ r5tD{9pU֫ %Qt3{sN9洒ױScAә5`"кkBop!`^˜Zz3{\bD 8c]碧ځAGJ 4*SŸɵ&'_oY;Pɺ5Gʬ Iw1h`7B8~[y>_RUA*Hg{HoL4єn;5~pEmm?nqci8R\F:M#wb6,qc+ӎIIF6!y]Qv7ui^DB_wˌ͑]pډ2ڧm" ? `Kmelk&OEٷ/LeYe>W vz9}J6?/x2 MMb^H>,|>cgLeFgޓuM,Gg=eJ<>o:/'1kasse/.git/objects/59/0000755000175000017510000000000012505101711014110 5ustar jonnypeoplekasse/.git/objects/59/77010d4031716b64d0bc23c375eef1f14ae7f90000444000175000017510000000034212505101711021144 0ustar jonnypeoplexAk0 wm~Km$9;)kasse/.git/objects/0a/0000755000175000017510000000000012505101710014152 5ustar jonnypeoplekasse/.git/objects/0a/edad19d1e93a1e82025ac6dc2fb714364afad10000444000175000017510000000016512505101711021564 0ustar jonnypeoplex+)JMU040f040031QH,(+dHë:UoE\b&@P\X̰;nٞV ŞV^h1$5 '$WrVw=o8+kasse/.git/objects/5e/0000755000175000017510000000000012505101700014162 5ustar jonnypeoplekasse/.git/objects/5e/d55c13f123ae147ef3f44b0d34e7a83075550a0000444000175000017510000000037112505101700021216 0ustar jonnypeoplexu?O0YOqT.ꂜ ]@K}J΅]`~wwi E ©s,T[Nz.EGt(}D䖥J1yP1M fGEvx$Fq" h[ƨAGkasse/.git/objects/3e/0000755000175000017510000000000012505101702014162 5ustar jonnypeoplekasse/.git/objects/3e/77d4d3f4b7131903bb32c109ed652bae4b59880000444000175000017510000000027012505101702021232 0ustar jonnypeoplexAN0 9NRi8#ze p9&@w"JR 4Oy&ŒѫS1037nZ0-XŢ:L3d 8IXkZx\๩t8 ~9o=ϡ/V}=z|Z7Ukasse/.git/objects/a5/0000755000175000017510000000000012505101700014156 5ustar jonnypeoplekasse/.git/objects/a5/d0f6aeb04e148952740ac30cb6315ab55b1b880000444000175000017510000000023712505101700021266 0ustar jonnypeoplexK 1 @] 6i ƍ"m032V({ǫ0\H>PBLH"Z&\q2TˬcYdHr֬$M(aBK0j`(P #1%W]/e>M}Ikasse/.git/objects/a9/0000755000175000017510000000000012505101706014170 5ustar jonnypeoplekasse/.git/objects/a9/cc1764b650da9f9e2d7dc2ececf55f1d74d26d0000444000175000017510000000440412505101707021716 0ustar jonnypeoplexXisAH $2*UyvwwfA©=@dR鞾i(\%[ƋK~J7F?س]ȉy%DtPV2-D,cZU&sLfC"o@{wC!ot2Z2ײJ%k-sfϊXZTI$ ̯DKoJ2a*cۢ?8MrIܭ|Mve\vv_ Kz͇;r\eJv Ǵږ+Rh+&"_b)5vցSQ+QIp q48PNTQWETg0NS k(8~@8}Ej*&?_|_J~ u>{ t TCКG3@?GEI%#^niS{+~+U,+Q:1v?0E+1Ist5a0uR>z &aa` ZG]d `m{Bx~ oH^]B 5LTn5j,5Rq)%ys8qۊ?ZI+I?i/H LczWyh)s#IL O) g})T= A5h[2 +(;tQ7LM Cd%4b 9Bw9> pB\$9D&S6}k^UQhatjSзhRq*#;dS:d۫ˋӗiރӸʃ~S= 1k~S§q2ڰq5n*@Uo@dg%qXݱp 4A|=!X(Ų] LY=װJODŽ=@ieoRDY3uՖ/i[ʰZMQtXV2Ei5 /FEZgyO3qHd$Dc1 9`j,8UB=M%B tAJbD҅Md9Wc<7ao[mX:ռq).tD\TlgJr;QndLe(*J΍oW \硫;q 6V!dVzx6>ISF;9Nɉ?~'"Uȵ4Eݶ'sgqS;!i-[j0n7o*:xs~DY-dXNacFWOQaƷB& p9gR}e+>}Ŝk`2\ /[q{7Jj|G*;tF:<6({^Ud>1$xcOမ ;$~x:j`M7&QiE/8at 8nNѪɒBS ky>-fc3Cy]"/ۉIJhDCmQcFJm&f&եzHaVEƓgSVBaV5hG*5&yVJyT[R\ ^0E-ڗ!}躟D4mOD}KЫ qU4Ӑ^iѠ EG6sjڜrpQ_ ټGf<)}t%5%8X6ɉɜD=H lۦb-}pnC.`Φ}x2]oSѢNSp[`h7.5@a!F0PF*A`}'MK%󖾘% <~FF9i6_9 @tPP:wlOt"!Yo$j1ߪF(TdgE5X#>B`Č{sGX ]r귍ĝ ,鄮 p!;u-HNTkW))Dc?;>7EG0f10zxz PQ/;yS/,Li~{?G+BeP &G̏Lbz{˴{lSJ4([7rk h]MGBЁ Dc`p:^dV? FtFӱ;9hH 30eû)!EfkRvw7).xD*$lllҀ]*h kasse/.git/objects/a0/0000755000175000017510000000000012505101706014157 5ustar jonnypeoplekasse/.git/objects/a0/641ff27057d66e6e4ada45353f5cb73e170b230000444000175000017510000000017612505101706021233 0ustar jonnypeoplexI 1=}$I4 Y_2 Ĉx:TmeθhГ(&:dɒ6MdrpVX[Kaµs|r?hGרJ 2;kasse/.git/objects/fa/0000755000175000017510000000000012505101707014246 5ustar jonnypeoplekasse/.git/objects/fa/2921d9df6558e60a972ad6189e5cbb5450c1e00000444000175000017510000000011312505101707021321 0ustar jonnypeoplexKOR07e+JM.SL/R(JM+N+AN/JMIS2 r+2r2RAR8I!kasse/.git/objects/48/0000755000175000017510000000000012505101710014105 5ustar jonnypeoplekasse/.git/objects/48/62061515047313961df0913361622920d048680000444000175000017510000000033512505101710020206 0ustar jonnypeoplex}P=k0ZChХ5c,%+^Y nwS^7c7(sk;TN9h U+&͡#N=5JàRIJDȘ6ȆNOooVGS^TY6bz$RŻ&'+Wa |)+oYr}6lu~mүԭ5~`pkasse/.git/objects/e1/0000755000175000017510000000000012505101704014162 5ustar jonnypeoplekasse/.git/objects/e1/fa5ffe2859863223364056cd6d6e0e01c4b20b0000444000175000017510000000040512505101704021225 0ustar jonnypeoplex+)JMU060f040031QH,(ad|fE,NK@դ'BYUIcx2#G[TSA?LQ~ DG(K44.xd@$VBU$n8Q3yge%`3 5M[_zPwp̽Nx<UUPZX uٳY]t~ev]*,.I,)-Z9lӖǟEtʘ8vM?ԗ51'Owݭa*)wkasse/.git/objects/0c/0000755000175000017510000000000012505101703014156 5ustar jonnypeoplekasse/.git/objects/0c/84cbeeae094ffad6f0c332f2a4ba352d23db0b0000444000175000017510000000055012505101703021717 0ustar jonnypeoplexMk@{ίsI!`Bq=H\ݐ²&)ewݴRɜޑb{`mۘjZCHڈF#olG7 )o9[Rڰ*K8sZfLf"Ǥ@!c~^<ω7R m M &/e-ʍJR&/3AGY820C@9}̛S y3#D2=-ZmP{j}X#)LG 0MŪrڠq*'A{T c Xgc煛I`P({S:S세]Jxm2_U[Vp.Kq=)rO3G#-H,!q1kasse/.git/objects/35/0000755000175000017510000000000012505101704014104 5ustar jonnypeoplekasse/.git/objects/35/abe0741c9fbe9398cb9fd3f58c44b488a672510000444000175000017510000000060612505101704021345 0ustar jonnypeoplex]R=O0eMaJP3dfX"74V@U9Z$"?ݸzS>m*~]siig!*T;THi[+EB DLΐHC 74~Cݸy$4Q3Uk].zΩ[la>'Ζ>_#<"K%{'{#eq 屢r!t˧ǷgBϲZ>4`r͢ag-xtppHbP;,Ts' :mxwR &ؚlX0+r)Oz=6ZOCcwT= R&/~;qUG4$ۧXoC?H#s ~ְkasse/scanner/0000755000175000017510000000000012505101674013022 5ustar jonnypeoplekasse/scanner/.gentex.py.swp0000644000175000017510000003000012505101673015544 0ustar jonnypeopleb0VIM 7.4زT :jonnyjtktp-debian~jonny/kasse/scanner/gentex.pyutf-8 U3210#"! UtpadgQ0/""")\end{document}""")""""""""""")\end{document}\bc{TEST}\begin{document}\barcode[code=Code39]{#1}\\{#1}}\newcommand{\bc}[1]{$\usepackage{makebarcode}\documentclass{article}print(r"""drinks = scanner.prices.keys()users = ["vale", "benni", "marco", "jonny"]import scannerkasse/scanner/gentex.py0000644000175000017510000000037012505101673014665 0ustar jonnypeopleimport scanner users = ["vale", "benni", "marco", "jonny"] drinks = scanner.prices.keys() print(r""" \documentclass{article} \usepackage{makebarcode} \newcommand{\bc}[1]{\barcode[code=Code39]{#1}} \begin{document} \bc{TEST} \end{document} """) kasse/scanner/scanner.pyc0000644000175000017510000000362512505101673015175 0ustar jonnypeople ӲTc@sdZddlTddlZeeZidd6dd6dd 6Zd d d d gZdejfdYZe dkrej ndS(shttp://localhost:5000/apii(t*Ng?tMATEgtLBIERg?tMCOLAtjonnytvaletbennitmarcotShcBs>eZdZdZdZdZdZdZRS(cCs$tjj|d|_|_dS(Nt(tcmdtCmdt__init__tuta(tself((s$/home/jonny/kasse/scanner/scanner.pyR scCs|j|_dS(N(tlowerR (RR ((s$/home/jonny/kasse/scanner/scanner.pytdo_uscCs|j|_dS(N(RR(RR((s$/home/jonny/kasse/scanner/scanner.pytdo_ascGs?d|j|jfGHtjd|jdtt|jGHdS(NtBUCHENtreceivertamount(R Rtctxtrequesttstrtprices(Rtargs((s$/home/jonny/kasse/scanner/scanner.pyt do_buchens'c GsEd|j|jfGHtjddd|jdtt|jGHdS(NtSTORNORtkassetsenderR(R RRRRR(RR((s$/home/jonny/kasse/scanner/scanner.pytstornoscGs |GHtS(N(tTrue(RR((s$/home/jonny/kasse/scanner/scanner.pytdo_EOFs(t__name__t __module__R RRRRR!(((s$/home/jonny/kasse/scanner/scanner.pyRs      t__main__( tURLtapiR tContextRRtusersR RR"tcmdloop(((s$/home/jonny/kasse/scanner/scanner.pyts     kasse/scanner/codes.aux0000644000175000017510000000001012505101674014625 0ustar jonnypeople\relax kasse/scanner/codes.log0000644000175000017510000001354512505101674014632 0ustar jonnypeopleThis is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) (preloaded format=pdflatex 2015.1.6) 13 JAN 2015 15:54 entering extended mode restricted \write18 enabled. %&-line parsing enabled. **codes.tex (./codes.tex LaTeX2e <2014/05/01> Babel <3.9l> and hyphenation patterns for 79 languages loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo File: size10.clo 2014/09/29 v1.4h Standard LaTeX file (size option) ) \c@part=\count79 \c@section=\count80 \c@subsection=\count81 \c@subsubsection=\count82 \c@paragraph=\count83 \c@subparagraph=\count84 \c@figure=\count85 \c@table=\count86 \abovecaptionskip=\skip41 \belowcaptionskip=\skip42 \bibindent=\dimen102 ) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty Package: amsmath 2013/01/14 v2.14 AMS math features \@mathmargin=\skip43 For additional information on amsmath, use the `?' option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty Package: amstext 2000/06/29 v2.01 (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty File: amsgen.sty 1999/11/30 v2.0 \@emptytoks=\toks14 \ex@=\dimen103 )) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty Package: amsbsy 1999/11/29 v1.2d \pmbraise@=\dimen104 ) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty Package: amsopn 1999/12/14 v2.01 operator names ) \inf@bad=\count87 LaTeX Info: Redefining \frac on input line 210. \uproot@=\count88 \leftroot@=\count89 LaTeX Info: Redefining \overline on input line 306. \classnum@=\count90 \DOTSCASE@=\count91 LaTeX Info: Redefining \ldots on input line 378. LaTeX Info: Redefining \dots on input line 381. LaTeX Info: Redefining \cdots on input line 466. \Mathstrutbox@=\box26 \strutbox@=\box27 \big@size=\dimen105 LaTeX Font Info: Redeclaring font encoding OML on input line 566. LaTeX Font Info: Redeclaring font encoding OMS on input line 567. \macc@depth=\count92 \c@MaxMatrixCols=\count93 \dotsspace@=\muskip10 \c@parentequation=\count94 \dspbrk@lvl=\count95 \tag@help=\toks15 \row@=\count96 \column@=\count97 \maxfields@=\count98 \andhelp@=\toks16 \eqnshift@=\dimen106 \alignsep@=\dimen107 \tagshift@=\dimen108 \tagwidth@=\dimen109 \totwidth@=\dimen110 \lineht@=\dimen111 \@envbody=\toks17 \multlinegap=\skip44 \multlinetaggap=\skip45 \mathdisplay@stack=\toks18 LaTeX Info: Redefining \[ on input line 2665. LaTeX Info: Redefining \] on input line 2666. ) (/usr/share/texlive/texmf-dist/tex/latex/makebarcode/makebarcode.sty Package: makebarcode 2008/07/27 Make various bar codes Package makebarcode Info: $Id: makebarcode.sty 224 2008-07-26 23:07:27Z zw $. (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) (/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty Package: keyval 2014/05/08 v1.15 key=value parser (DPC) \KV@toks@=\toks19 ) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) ) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/kvsetkeys.sty Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) ) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/etexcmds.sty Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) (/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ifluatex.sty Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) Package ifluatex Info: LuaTeX not detected. ) Package etexcmds Info: Could not find \expanded. (etexcmds) That can mean that you are not using pdfTeX 1.50 or (etexcmds) that some package has redefined \expanded. (etexcmds) In the latter case, load this package earlier. ))) \ZWbc@ctr=\count99 \ZWbc@dimX=\dimen112 \ZWbc@dimH=\dimen113 \ZWbc@dimB=\dimen114 \ZWbc@dim@=\dimen115 \ZWbc@hpbox=\box28 \ZWbc@ITFbox=\box29 \ZWbc@ITFwidth=\dimen116 \ZWbc@ITFtoks=\toks20 ) (./codes.aux) \openout1 = `codes.aux'. LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 8. LaTeX Font Info: ... okay on input line 8. LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 8. LaTeX Font Info: ... okay on input line 8. LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 8. LaTeX Font Info: ... okay on input line 8. LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 8. LaTeX Font Info: ... okay on input line 8. LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 8. LaTeX Font Info: ... okay on input line 8. LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 8. LaTeX Font Info: ... okay on input line 8. Overfull \hbox (4.43916pt too wide) in paragraph at lines 11--39 []$[]$ $[]$ $[]$ [] Overfull \hbox (4.43916pt too wide) in paragraph at lines 11--39 []$ $[]$ $[]$ [] Underfull \hbox (badness 10000) in paragraph at lines 11--39 [] [1 {/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./codes.aux) ) Here is how much of TeX's memory you used: 1450 strings out of 493105 19088 string characters out of 6137073 83287 words of memory out of 5000000 4955 multiletter control sequences out of 15000+600000 4094 words of font info for 16 fonts, out of 8000000 for 9000 1141 hyphenation exceptions out of 8191 37i,8n,21p,263b,202s stack positions out of 5000i,500n,10000p,200000b,80000s Output written on codes.pdf (1 page, 16626 bytes). PDF statistics: 12 PDF objects out of 1000 (max. 8388607) 7 compressed objects within 1 object stream 0 named destinations out of 1000 (max. 500000) 1 words of extra memory for PDF output out of 10000 (max. 10000000) kasse/scanner/api.py0000644000175000017510000000121612505101674014145 0ustar jonnypeopleURL = "http://localhost:5000/api" import json import urllib class APIError(RuntimeError): """Remote Operation failed""" def __init__(self, message="Remote fail", errors=[]): super(APIError, self).__init__(message) self.errors=errors def request(url = None, **kw): data = urllib.urlencode(kw) print(data) if url is None: url = URL return json.load(urllib.urlopen(url, data)) class Context: def __init__(self, *args, **kw): self.kw = kw self.args = args def request(self, *args, **kw): d = dict(self.kw) d.update(kw) return request(*(self.args+args), **d) kasse/scanner/codes.tex0000644000175000017510000000145512505101673014645 0ustar jonnypeople\documentclass[a4paper]{article} \usepackage{amsmath} \usepackage{makebarcode} \newcommand{\bc}[1]{$\stackrel{\text{\barcode[code=Code39]{#1}}}{\text{#1}}$\\[1cm]} \begin{document} \setlength{\parindent}{0cm} \begin{minipage}{0.4\textwidth} \begin{center} \bc{U VALE} \bc{U MARCO} \bc{U BENNI} \bc{U JONNY} \end{center} \end{minipage} \begin{minipage}{0.2\textwidth}\hspace{1mm} \end{minipage} \begin{minipage}{0.4\textwidth} \begin{center} \bc{A CLUBMATE} \bc{A MATECOLA} \bc{A LOSCHICOLA} \bc{A LOSCHERBIER} \bc{A ICETI} \end{center} \end{minipage} \\[2cm] \begin{minipage}{0.4\textwidth} \begin{center}\bc{BUCHEN}\end{center} \end{minipage} \begin{minipage}{0.2\textwidth} \hspace{2cm} \end{minipage} \begin{minipage}{0.4\textwidth} \begin{center}\bc{STORNO}\end{center} \end{minipage} \\ \end{document} kasse/scanner/scanner.py0000644000175000017510000000241412505101673015025 0ustar jonnypeopleURL = "http://localhost:5000/api" from api import * import cmd ctx = Context(URL, password="essakkasse", sender = "kasse", user="kasse") prices = { "clubmate": 0.50, "loscherbier": 0.0, "iceti": 0.50, "matecola" : 0.4, "loschicola": 0.5 } users = ["jonny", "vale", "benni", "marco"] class Sh: def __init__(self): self.u = self.a = "" def do_u(self, u): self.u = u.lower() print("user "+u) def do_a(self, a): self.a = a.lower() print("article "+a) self.do_buchen() def cmdloop(self): while True: command = raw_input("scan> ").lower() if command[0] in "ua": arg = command[1:] f = getattr(self, "do_"+command[0]) f(arg) else: f=getattr(self, "do_"+command) f() def do_buchen(self, *args): print("BUCHEN", self.u, self.a) print(ctx.request(receiver = self.u, amount = str(prices[self.a]), comment = self.a)) return def do_storno(self, *args): print("STORNO", self.u, self.a) print(ctx.request(receiver = "kasse", sender = self.u, amount = str(prices[self.a]))) if __name__ == '__main__': Sh().cmdloop() kasse/scanner/api.pyc0000644000175000017510000000300512505101674014306 0ustar jonnypeople rTc@sWdZddlZddlZdefdYZddZdddYZdS( shttp://localhost:5000/apiiNtAPIErrorcBseZdZdgdZRS(sRemote Operation faileds Remote failcCs#tt|j|||_dS(N(tsuperRt__init__terrors(tselftmessageR((s /home/jonny/kasse/scanner/api.pyRs(t__name__t __module__t__doc__R(((s /home/jonny/kasse/scanner/api.pyRscKsBtj|}|GH|dkr)t}ntjtj||S(N(turllibt urlencodetNonetURLtjsontloadturlopen(turltkwtdata((s /home/jonny/kasse/scanner/api.pytrequest s   tContextcBseZdZdZRS(cOs||_||_dS(N(Rtargs(RRR((s /home/jonny/kasse/scanner/api.pyRs cOs0t|j}|j|t|j||S(N(tdictRtupdateRR(RRRtd((s /home/jonny/kasse/scanner/api.pyRs (RRRR(((s /home/jonny/kasse/scanner/api.pyRs ((R R R t RuntimeErrorRR RR(((s /home/jonny/kasse/scanner/api.pyts    kasse/scanner/codes.pdf0000644000175000017510000004036212505101674014617 0ustar jonnypeople%PDF-1.5 % 3 0 obj << /Length 2956 /Filter /FlateDecode >> stream xڭ]MxG GI"Oq|%?)Z9[[a>V5{8dUsMD.rTBO?/K ˿s ?/orFq4crq!6jB,l4R]!0ȋ,UcWcQ2Bj]#%ĚX+.xv,bP*;j -VJ8YHupɗ`0CQyW Ǜ#ac}-6+|]MijWXq4Tpś12WO)={oonoͶa;i#iEȡA\a/DZhwŒ V(GF 56Xd<<8K8Lf e7m6_")&q06v@pĎqC&q@pOoT kl4% #E\%b$بA&F\C%.j&n!b@a2dW[m3pşo^G+*&9@]+_~xdz￯6Xaһx#Ӣ=JOua0L ښF a2cci.4 #Ӣƃ$Du1 b5I)Cܳ=F!ӈMI.T..6&`(mIbx-^ݽW慢< e Bq\Iњ̣xO2Op'a2O"-T j\Vl#+Iў2#v'̣'*Op'a1Vsh*O*O"v'aw'ʣG6rDZ(Ķߩʓ0\)1&*k*o~^u޾۷*~bI*Pue Pw ammTb{ }vxHB(e?%a{E&ʰDC6FEX4"b-bIp"Y!f%ksA(Pd^WpK51&.Ұ*׈Ed?n]$nAks2)ڣ\ mΧѡ1BYl.v[ QL1f#';x@k&BsKGślN-5\YbX*'q8kb~FhےxT.(FL%gמo\Vk Å4ݧW?|>˳1̯a+fL8̘1̘FlfLp3afldfldfL"&7c*׷cT%"1 c6afK،}2ąz0BmF-E\*]"qG9sD sc\FMj4Í77&gǸ _8owclƬlZXbc cw3F623߄;\cbw[݋i4 bdŸFhb}uNx1DWC^V,4ڒ #HfZ->Ybw 1kKȸUZXq{'U.fT!MYKV!>-q'{?ia%rfɊa9D&hgPGi`g+nkVXxAfcOxHMXmn`%b3/lTd&񚑥,v4F163ԒDeJS%2o'j5UEfNs p+#QLiaaase{|zV)ZȽ*Nku?+p97٦ՐB\b'+c'?V }@_{z;4Qz1`b5Qۯ=P"ZB52U&N۶Fl5 cIǎ{|ak$*b*XHĶNZAjIl;\#!]kcZŘMdZB8^b? q=%m]#F) FIl[B8j\% #۫\VЈe _ s$\[B#zIlxU#qi$4b7h#4:}Xxc1;q9iLq6uv,?~XW7"Sz@d8a oJ%^@ķ~V*Of[/fem܋IN;V"Q%ӋIW|2 {T#DvĻ2(^L"v/۫TQ%sWp3&afL"v3FfL!>͘q<A۩Fsh^jsz1%ӋIŸ݋I2Il/Kħ05qv֬A&b\#btj=,{-kR*+X0Ӭa9W?ldjNLD"}I@ ${pf)Z·a=kv3;ld=#-,6bg T1ۗ=4 eؿA wKl_adh*bA@&ѿh^;PsU} Hs`xa?X1hQ[r"aE<2x+iap{O""aE< Êxdg~Hl/pCg-0Vay ׊x4 +iVE<n}w./E%;~ӝ& endstream endobj 8 0 obj << /Length1 1603 /Length2 11259 /Length3 0 /Length 12307 /Filter /FlateDecode >> stream xڍP۶5 AKCpwwwwi! NpK ݂Oޫzs1%:PWTce3!PRj\(. 0e 4u}I):rnvVv++7   "@ tAwprYY#Ɯ;@ 27M]oM vuucf`2warpex\j@;a=Θ( @dy-΀uY# f`ebOr657ww4{VK,0[14sqx7u7ٙU)@JT`?;]]\@vZdmʒ` q{{ O} gؽY[` [Xi͑Y rrJc&BWftppN5^o8:8,ߚ,o>.@V7B`eX]f@+obA}7Xs2|_Y^USNOs0r8YHv0*|e޿}ThYZRrxc-@/ X8Y>D".H/5_di\@m T*-@n[+j`+"Z\ͭfr?[fU\@/j۾=.oK|ۜN) 6wbl\SggS/K~Cַ]zEb3֞ύrqEF\f7Y_ `f0̲"ܿ-¿-⿈/zˠA_A_A_փ-ֿ-z{5Fs7g緗/_ 4GXs0 i%`NeYpp{@J[|#umyKZd簥.5AN$Dh}?{"F ]g'_@[r9Nn<(*yw}ҞeKas;\Oe?c4 g(s2ga]0cul5'dw|ccMM0%w!hKOYKA׉;ETd~Ԗf?gy7i04ʺi/<$kNdƷy5OQ,krٺ,>\kxswwNiP?u噖ipFIgu {-ѠDS)Lk%WqɪPP=~hfL]; G ˏbJ4OepsXև>EFW߃\>}dM/_>ǜodv*۵JtD#VУ#a"B@9`|QfnBP͓tljLgmV-!1Aګc2n\{ʾSlek*gaYT\1)X\FV$ !/۠UrISƒp:KOp:~f]Zag[ n>k j,"W<:iҞ +_6dYH{0I;MXK`ʹTd#US`(9,_ʹB:'HQwG6>{g&/레h97Bk[q+<֨5^D09B4ɇ-sTE_z+PR1{䄪ZbbD~{ZqCK |S5 fŽ6AL;"G6~KLu"T&xŎșa_RoKx?Q`u+Y\,D>ܖ@L*D@Lw$J="G+]FAoZT<CW=ѵG ~ ,r*hE4 g1G0.Uѷ9OQA>~H/ƅ7dyQO)hez0T2)ÈX{%qbMc%tH5\(ǘv/ sWYjDկ=Rte }#%qIpA:FRkU&QROUdUvaݕ25)K)zT[zfɴF9Z*3JN!&In/gd2 QG^qm6l|D:~ɴ@3)}Tamu7#5^+VXo .MC:9Dx2qq(\sx&moG$,`u3P+ )t*ͨvH-x[z{n׉yWbvi}wp~+W4!i)c {G꽮wvbs+ޓ&e7EJ%!=JGYީxrȄ`i?5/Iab]q.\>mOޱ&s*9 q˵=_60CD~*Ve@qүKvo#U5¢x5G.RS3"V3~YoK7Szmd 4s[%j##MAzB.ߪIɡ6QPN ZꨫlAe{Y]sy0vsx9SiUT Q, ccdd1 g ?ƄfD^,| {K3PwU/ayӴ]a2 /c񩑌Z]jmD<%iXb/:\:hArƟ%Dv tSgMp$#8}0Px;jқU\(_# p:"{\⏐v4Ӎ$af{G%NynHg`/miLR^t5[ޫX,MHף{HYݝl|y}B#tAQYCuX[VtkQ}02]Ɲ/^E]I~^"C)\]P΀)/BM26yh[.AIL=BsչUv}TIj.qSR&MMy["2TI0'@w0f`TVm{i(W4=V9YLRلܧ fK?Ñ-r$=jKE)RmgƦfݾ#Ā_6cd2Q2cIE׍_ٔkvE 4\@WD-n-ș*Lvʹ!+U<2췝6d"E,3DS%_`]%v_wU&Բv9d; O*=?|`%SNMmL2Nҷ*yܼ)/V.!X;sv{}${^1| :Bdt͡\t*-TKiu8MU1JElygPjwA Ozo᭏xQ(il6cī9\nǒaf%mY ~mVc:L~vg Sh]z"NCҽhZڍX:qՕ9ze=ft aS-k%8QB~ײ̊ךPTdg ?g9laөh hК.:ȭ"gec'3obؘE 8B@+:!cYfiYpL+|<~z|Ŷp7`wQN^в4I6h e]~$]_%615'z~[v2URD3bսNQ-Ue~i#=BQqYd/9ܒ:7Jע.I5<>̩21}9$݈-mIJ;\u>,U)$r CLPKZhI+1`WH17:5B@ZGVTxH 1ҳElhM#^ ~kI&M;Gh #Z=KɏOT㇉$n0E# E`h& ?}@ /YmUy2:S}ȌCgRKRQ23%fW/pB?r_O2V{= kZ`ۅh7O 28:r'J1AJݲ23cW]|"R{Jp:+,ms-RMֱKLhaIB~ zJ͒ؓWշ1j0F3]_^t78Mbq>{vCifFQ7HjΡq"-= k?-⥓eÙn4 dž?e\8vۖʰ](VY+A+YA[uf94÷na󡰥z;i0E$AJ;vWu2n@74/OaA3/l־G4vLO˜~E|“\r=I%"^=/k @K$vUT {L)o h/²Q%Ǵ"}6)fzp(% "#1>fA}}&f<Zhӻwn=c4+y~NU/a67*pX66"2JqPqܣ`994vQ=5(8VXN G \ ͓Vh َ5I$6'c[ eey$|k|GP9ÉHCTrc!e"8 Z Zq% Y*Bӭ#vTF:OE]tʺ d"֊9.=ԗ.H 3ଽ@Q1N? R1Vt?ki2}15{Y@aOa J%3ϓt5:6"~`u;(}O궋Zƚ]a =*0OsJ~whˮOVb+"ڜ$C %@?xrTX$+Z>xOih@eIԡ16FqkU*9%RԖ-.t \BioS6Y7#j$/{@@2ɖDҦ_nfsm|2ltm8tsާn0[|Hz,fď|_WBv7J,|QD} iD;seRdN \V}Rg!"̖(+W}͢4@V` Xҭ GUkh>2ftA C\CkGkVժD=ULh` Ixx2O'.Y gT?d>H =2w`Z+]G6D7Vtl"UΪx 0B#3D`_ d"Yţ="̔QVM>$׈=$N?v/7XNͿ;;kGf$b5MaV3fя.|s]CиF-~sfu qR̎B-5!+XphVn'9_ufBvm B:T+}`M1eNByx=79d::mgvGl4hY] z*B Կ|-Rg1xGjTTn~ޟIK{I1KAm/atK]ylm> ˺ dmMˬ}O. sZq~ \B,mE/ctUe{I5JՃ+v]J/hR-f=^VسEw# *Td3 1-]}a9~?LY<0)n x)7s&ɖh? F#gH~?k*:Щsָ3NS?66)8rInB_oLGGsCMWv1*p!PT%-¯_|8X_lUz\NjgT)&qZԛ]TI$'ޚm7R8k 띔|jSW)1Sm '녏Pw3YO,~EwYv}De2:3Šn z^CJ~' A t ?B2.LmF8"_sv{_/%}9/8ۣ.+dClϱ=lJ=:zqi-~4HlVowAR|a&EmjgG̎kHqZ#|#g )!ilA'}sdzѮLe<|FK6ļy&ٹT-!TjhGyci.{`Tkb68%m"bp[|;w9WT@ײ:DF!6RU{^jfH&xZ THud7Y3jM2ATV]0꥽iYnmK0^+y\_vǝصtFHldAFaKׁ0),bв:n>A\.U~v@i~}{ dR'etbU4S/ħw|MJ*jY(}x7m$.뗳D 0n:uX97~^|`*.PS l/I$`RAu#  G3Ut&-A "+neAQs' cRFsq,Scc> }:bLfˣ̹ * fk%q U~7F~2+8 At/$h4ߌQv n6Gj0VBf|Ngq!hU.s,a֔ۯrT5{/1w?)Ĩv3R?Q-킱~ō7dSGk *\]B8Ҁxi%6h$Al ]xHg;F,ZHf^@a;{ޠ)UpU uU^r̀ע]V>q"{uy#[;"Ύp]9<3b,o*j) dXPkWa/91iuʟ|#~mO@,R8ռz,v,/QϭVhy'gKCF^|ujO|:U^(QBu-˂a\$"d#SsKQUz'))؆hr'd׆裻Y4/L!ŕ@a\9W҅锾S/~7c9_JF^iB訙~ ?&m1\>Iqu cU{;Uyq2B,YG"Ǘ!9>;kGTajMyZvة:vxVRLTZ^mU07Ӌ1.3@UhT|Fd~9V3p!.oDQaӶdDF6I2xǺ"JPNL}<Щ-qD$q+ Pi2st̾6\CPUNQxej-?W& Ν@*NM`E'ʄr:"7; 7q &kSZmْo< tqAQ9@cRZ[ ]P[R{k&*zu9Ǹ:'ŠA*v@(Wx>]* h*DͤקoqԯE'ClR/"P[G{"j ʠfXßk5u^gXf,締}E|K+vK 1ud⵱fS݅Ψ #1~Fꧣ-],N~.G@ >HeU܀v\fnJ8ųvN! >kI!fNrN,KKdLQG 0$Y{Qc s/'Љ1cJ1N> todVku,̠.v7[.t&*bNSGfD~ob?Q֓QѓLbHe;sjٝ (Lw_фG6$xrNN=WbKF{ɸ~NQyRz:}\NI #gF) zu}n滝us:*r"]h~aӡ*.=FwQ[3J``LIY+9;Ί&KJLbX(Ǯyf<14/K_|~nLgNaqzc}i,M+6:?sqT KrJq` t1|Dx2d=ťHN}pIVؚU޴fp @զ畕4{+ I%ۼ1@dOʹzXJ+[;iX(B8S‰/Ķs&Q=RHz!U 5F-+8*\ED\ wTʱm:7-~8>t?ɱ9y~<<-WVfǭ}Ƥ/̚X͕T.4bGҞ("S*P5@_Rd Xg1 d >N48R~@0 ޣKGڱ~Z l}U,]4&$9dAo|5U ZSA]P5{T& Yvp?DZ!$* endstream endobj 11 0 obj << /Producer (pdfTeX-1.40.15) /Creator (TeX) /CreationDate (D:20150113155413+01'00') /ModDate (D:20150113155413+01'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2015/dev/Debian) kpathsea version 6.2.1dev) >> endobj 5 0 obj << /Type /ObjStm /N 7 /First 40 /Length 468 /Filter /FlateDecode >> stream xڅRn0+آDRR!vA Yc $!%4qr-p0Rd*@pZ`<pr4Ee̚Cg ΍mNmi,y`fu1maP\N& yK:2w oǀyBT*C۔ 2/sy`4ko l~ŰFhQ) ġHѫr5kH9g_d7=v 4lc״}'~/* qOnb#YĖ)1xejG$ ХڈuWrr~љ9h∓Ůh| N1ïxxw8{s\q9LV:с1-cgyÖ׭ܵ !Ïz,`7Mb(ZX Gܜ3TA/yݿ5Ο endstream endobj 12 0 obj << /Type /XRef /Index [0 13] /Size 13 /W [1 2 1] /Root 10 0 R /Info 11 0 R /ID [<6AF261D7EB2782A57C903573D176BC01> <6AF261D7EB2782A57C903573D176BC01>] /Length 50 /Filter /FlateDecode >> stream xc`` @Ѷ D1#+mJ1i endstream endobj startxref 16326 %%EOF kasse/app.py0000644000175000017510000002266412505101673012534 0ustar jonnypeople#!/usr/bin/python3 from __future__ import print_function from flask import * import flask.ext.login as fl from flask.ext.sqlalchemy import SQLAlchemy from flask_wtf import Form from wtforms import fields as ff import wtforms.validators import jinja2 import datetime import sys import os from crypt import crypt GET, POST = "GET", "POST" app = Flask(__name__) app.secret_key = os.urandom(32) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' app.jinja_env.undefined = jinja2.StrictUndefined db = SQLAlchemy(app) login_manager = fl.LoginManager() login_manager.init_app(app) @login_manager.user_loader def user_loader(login): return User.query.get(login) login_manager.login_message = "Du bist nicht (mehr) angemeldet." class User(db.Model, fl.UserMixin): login = db.Column(db.String(), primary_key = True, nullable = False) password = db.Column(db.String()) def get_id(self): return unicode(self.login) def query_again(self): return User.query.get(self.login) def auth(self, password): return crypt(password, self.password) == self.password class Payment(db.Model): id = db.Column(db.Integer, primary_key = True, nullable = False) sender_login = db.Column(db.String(30), db.ForeignKey("user.login"), nullable = False) sender = db.relationship("User", backref = "sent_payments", foreign_keys = [sender_login]) receiver_login = db.Column(db.String(30), db.ForeignKey("user.login"), nullable = False) receiver = db.relationship("User", backref = "received_payments", foreign_keys = [receiver_login]) cents = db.Column(db.Integer, nullable = False) comment = db.Column(db.String(200)) ok = db.Column(db.Boolean, default = True) time = db.Column(db.DateTime, default=datetime.datetime.utcnow) class UserField(ff.TextField): def process_formdata(self, valuelist): super(UserField, self).process_formdata(valuelist) self.data = User.query.get(self.data) if self.data is None: raise wtforms.validators.ValidationError("user not found") def _value(self): return "" if self.data is None else self.data.login class MoneyField(ff.DecimalField): def process_formdata(self, v): super(MoneyField, self).process_formdata(v) if self.data is not None: self.data = int(round(float(100 * self.data))) else: raise wtforms.validators.ValidationError("Kein Betrag angegeben") def _value(self): if self.data == None: return "" else: return "%.2f" % (self.data / 100.0) class SimplePaymentForm(Form): amount = MoneyField(places=2, label="Betrag") user = UserField(label = "Benutzer") comment = ff.TextField(label = "Zweck") class LoginForm(Form): username = UserField() password = ff.PasswordField() class ApiForm(Form): user = UserField(label = "user") password = ff.PasswordField(label = "password") sender = UserField(label = "sender") receiver = UserField(label = "receiver") amount = MoneyField(label = "amount") comment = ff.TextField(label = "comment") @app.route("/") def index(): if fl.current_user.is_authenticated(): return redirect(url_for("status")) else: return redirect(url_for("login_page")) def JSON(obj): import json data = json.dumps(obj) r = make_response(data) r.mimetype="application/json" return r @app.route("/api", methods = [POST, GET]) def api(): form = ApiForm(csrf_enabled=False) if request.method == POST: errors = [] if form.validate_on_submit(): if form.user.data.auth(form.password.data) and form.user.data in (form.sender.data, form.receiver.data): p = Payment( sender = form.sender.data, receiver = form.receiver.data, cents = form.amount.data, comment = form.comment.data) db.session.add(p) db.session.commit() return JSON({"status": "ok"}) else: errors.append(["action", "permission denied"]) for (f,e) in form.errors.items(): errors.append([f, e]) return JSON({"status": "fail", "errors": errors}) else: return render_template("api.html", form=form) login_manager.login_view = "login_page" @app.route("/login", methods = [POST, GET]) def login_page(): form = LoginForm() if request.method == POST and form.validate_on_submit(): u = form.username.data p = form.password.data if u.auth(p): fl.login_user(u) return redirect(url_for("status")) flash("login failed") return render_template("login.html", form=form) @app.route("/logout", methods=[POST]) def logout(): if Form().validate_on_submit(): fl.logout_user() return redirect(url_for("login_page")) else: flash("CSRF?") return redirect("/") @app.route("/gave", methods = [GET, POST]) @fl.login_required def gave(): form = SimplePaymentForm() if request.method == POST and form.validate_on_submit(): sender = fl.current_user receiver = form.user.data cents = form.amount.data p = Payment(sender = sender, receiver = receiver, cents = cents, comment = form.comment.data) db.session.add(p) db.session.commit() flash(eur(cents)+Markup(" an %s gegeben")%receiver.login) return redirect(url_for("status")) return render_template("gave.html", form = form) @app.route("/got", methods = [GET, POST]) @fl.login_required def got(): form = SimplePaymentForm() if request.method == POST and form.validate_on_submit(): receiver = fl.current_user sender = form.user.data cents = form.amount.data p = Payment(sender = sender, receiver = receiver, cents = cents, comment = form.comment.data) db.session.add(p) db.session.commit() flash(eur(cents)+Markup(" von %s genommen")%sender.login) return redirect(url_for("status")) return render_template("got.html", form = form) class PurchaseForm(Form): users = ff.SelectMultipleField(label = "Benutzer") amount = MoneyField(label = "Betrag") comment = ff.TextField(label = "Zweck") def __init__(self, *args, **kw): super(PurchaseForm, self).__init__() self.users.choices = [(u.login,u.login) for u in User.query.all()] @app.route("/purchase", methods=[GET, POST]) @fl.login_required def purchase(): form = PurchaseForm() if request.method == GET: form.users.data = [fl.current_user.login] if request.method == POST and form.validate_on_submit(): users = [] for uid in form.users.data: u = User.query.get(uid) if u is None: form.users.errors.append("Benutzer %s existiert nicht"%uid) else: users.append(u) if not users and not form.user.errors: form.users.errors.append("Kein Mitverwender angegeben") if not form.users.errors: cents = int(round(form.amount.data * 1.0 / len(users))) cmt = form.comment.data if cmt == "": cmt = None for u in users: if u.login != fl.current_user.login: p = Payment(sender = fl.current_user, receiver = u, cents = cents, comment = cmt) db.session.add(p) db.session.commit() names = ", ".join([u.login for u in users]) flash(Markup("Einkauf für %s, je %s übernommen")%(names, eur(cents))) return render_template("purchase.html", form = form) @app.route("/status") @fl.login_required def status(): u = fl.current_user r = sum(p.cents for p in u.received_payments) s = sum(p.cents for p in u.sent_payments) balance = s - r return render_template("status.html", u = fl.current_user, balance = balance, form = Form()) def eur(cents): return Markup("%.2f€") % (cents / 100.0) app.jinja_env.globals["eur"] = eur def adduser(name, password = None): """Create the a user with login NAME prompt for password intereactively, if not supplied as second argument""" import getpass, binascii if password is None: password = getpass.getpass() again = getpass.getpass("Again: ") if password != again: raise ValueError("passwords don't match") random = binascii.b2a_base64(os.urandom(20)) algo = "$6$" hash = crypt(password, algo+random) u = User(login = name, password = hash) db.session.add(u) db.session.commit() if __name__ == "__main__": _shell_locals = dict(locals()) args = sys.argv[1:] if args == []: app.run(host="::", debug=False) elif args == ["debug"]: app.run(debug=True) elif args == ["setup"]: db.create_all() jonny = User(login = "jonny", password="ash/3bldtbcqc") vale = User(login = "vale", password="asFh8r1oVbGqk") platte = Payment(sender = vale, receiver = jonny, cents=9500, id = 42, comment = "ausgelegt: platte") db.session.add(jonny) db.session.add(vale) db.session.add(platte) db.session.commit() elif args == ["shell"]: import code sys.ps1 = "mt> " code.interact(local = _shell_locals) else: print("invalid arguments: %s"%args, file=sys.stderr) sys.exit(1)