§
    ×jÀr  ã                   óJ  — d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZmZ ddlmZ ddlmZ  ee¦  «                             ¦   «         j        Zedz  dz  Zej                             d	d
¦  «                             d¦  «        Zd„ Zedz  Zedz  dz  ZdddddœZ dZ!dddddœZ"i Z#i Z$ G d„ de	j%        ¦  «        Z&d„ Z'd„ Z(d„ Z)d„ Z*d „ Z+d!„ Z,d"„ Z-d#„ Z.d$„ Z/d%„ Z0d&„ Z1d'„ Z2d(„ Z3d)„ Z4d*Z5 G d+„ d,e¦  «        Z6d-„ Z7e8d.k    r e7¦   «          dS dS )/uD   Wildfleisch-Reservierungsserver, ausschlieÃŸlich Standardbibliothek.é    N)Úcookies)ÚBaseHTTPRequestHandlerÚThreadingHTTPServer)ÚPath)Úparse_qsÚdatazwildfleisch.sqlite3Ú	WILD_BASEÚ ú/c                 ó\   — |                       d¦  «        sd| z   } t          r
t          | z   n| S )uF   Pfad fÃ¼r Links, Formulare und Weiterleitungen, inklusive URL-PrÃ¤fix.r   )Ú
startswithÚBASE)Úpaths    ú!H:\dev\projekt_wildfleisch\app.pyÚur      s2   € à�?Š?˜3ÑÔð Ø�T‰zˆÝÐ(�4�$‰;ˆ; DÐ(ó    Ú	beispieleÚimagesu   Hirsch Â· RÃ¼ckenu   Hirsch Â· Schulteru   Hirsch Â· Keuleu   Hirsch Â· Ragout)zruecken.jpgzschulter.jpgz	keule.jpgz
ragout.jpgi€„ z
image/jpegz	image/pngz	image/gifz
image/webp)ÚjpgÚpngÚgifÚwebpc                   ó   ‡ — e Zd Zˆ fd„Zˆ xZS )ÚDatabasec                 óŒ   •— 	  t          ¦   «         j        |Ž |                      ¦   «          S # |                      ¦   «          w xY w©N)ÚsuperÚ__exit__Úclose)ÚselfÚargsÚ	__class__s     €r   r   zDatabase.__exit__,   s:   ø€ ð	Ø#•5‘7”7Ô# TÐ*à�JŠJ‰LŒLˆLˆLøˆD�JŠJ‰LŒLˆLˆLøøøs	   ƒ- ­A)Ú__name__Ú
__module__Ú__qualname__r   Ú__classcell__)r"   s   @r   r   r   +   s8   ø€ € € € € ðð ð ð ð ð ð ð ð r   r   c                  ó”   — t          j        t          dt          ¬¦  «        } t           j        | _        |                      d¦  «         | S )Né
   )ÚtimeoutÚfactoryzPRAGMA foreign_keys=ON)Úsqlite3ÚconnectÚDBr   ÚRowÚrow_factoryÚexecute)Údbs    r   r,   r,   3   s9   € Ý	Œ� RµÐ	:Ñ	:Ô	:€BÝ”[€B„NØ‡J‚JÐ'Ñ(Ô(Ð(Ø€Ir   c                  ób  — t           j                             dd¬¦  «         t          ¦   «         5 } |                      d¦  «         d„ |                      d¦  «        D ¦   «         }d|vr|                      d¦  «         d d d ¦  «         n# 1 swxY w Y   t                                d¦  «         d S )	NT©ÚparentsÚexist_okaõ  
        CREATE TABLE IF NOT EXISTS admin (id INTEGER PRIMARY KEY CHECK(id=1), salt TEXT NOT NULL, hash TEXT NOT NULL);
        CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, description TEXT NOT NULL, unit TEXT NOT NULL, stock INTEGER NOT NULL CHECK(stock>=0));
        CREATE TABLE IF NOT EXISTS reservations (id INTEGER PRIMARY KEY, reference TEXT UNIQUE NOT NULL, name TEXT NOT NULL, contact TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'offen', created TEXT DEFAULT CURRENT_TIMESTAMP);
        CREATE TABLE IF NOT EXISTS items (reservation_id INTEGER REFERENCES reservations(id), product_id INTEGER REFERENCES products(id), quantity INTEGER NOT NULL CHECK(quantity>0), PRIMARY KEY(reservation_id, product_id));
        c                 ó   — h | ]
}|d          ’ŒS )é   © )Ú.0Úrows     r   ú	<setcomp>zinitialize.<locals>.<setcomp>C   s   € ÐOÐOÐO˜c�3�q”6ÐOÐOÐOr   zPRAGMA table_info(products)Úimagez*ALTER TABLE products ADD COLUMN image TEXTé€  )r-   ÚparentÚmkdirr,   Úexecutescriptr0   Úchmod)r1   Úcolumnss     r   Ú
initializerC   :   sù   € Ý„I‡O‚O˜D¨4€OÑ0Ô0Ð0Ý	‰Œð 	E�bØ
×Òð ñ 	ô 	ð 	ð PÐO R§Z¢ZÐ0MÑ%NÔ%NÐOÑOÔOˆØ˜'Ð!Ð!Ø�JŠJÐCÑDÔDÐDð	Eð 	Eð 	Eñ 	Eô 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eøøøð 	Eð 	Eð 	Eð 	Eõ ‡H‚HˆU�O„O€O€O€Os   °AB
Â
BÂBc                 ó¬   — t          j        |                      ¦   «         t                               |¦  «        ddd¬¦  «                             ¦   «         S )Né @  é   r7   )ÚsaltÚnÚrÚp)ÚhashlibÚscryptÚencodeÚbytesÚfromhexÚhex)ÚpasswordrG   s     r   Úpassword_hashrR   I   sA   € ÝŒ>˜(Ÿ/š/Ñ+Ô+µ%·-²-ÀÑ2EÔ2EÈÐRSÐWXÐYÑYÔY×]Ò]Ñ_Ô_Ð_r   c           	      ó<  — t          | ¦  «        dk     rt          d¦  «        ‚t          j        d¦  «        }t	          ¦   «         5 }|                     d|t          | |¦  «        f¦  «         d d d ¦  «         n# 1 swxY w Y   t                               ¦   «          d S )Né   z Mindestens 12 Zeichen verwenden.é   z+INSERT OR REPLACE INTO admin VALUES (1,?,?))	ÚlenÚ
ValueErrorÚsecretsÚ	token_hexr,   r0   rR   ÚSESSIONSÚclear)rQ   rG   r1   s      r   Úset_passwordr\   M   sÚ   € Ý
ˆ8�}„}�rÒÐÝÐ;Ñ<Ô<Ð<ÝÔ˜RÑ Ô €DÝ	‰Œð i�bØ
�
Š
Ð@À4ÍÐW_ÐaeÑIfÔIfÐBgÑhÔhÐhðið ið iñ iô ið ið ið ið ið ið iøøøð ið ið ið iå‡N‚NÑÔÐÐÐs   Á'A8Á8A<Á?A<c                 óf  — |                       ¦   «         |                      ¦   «         }} dt          | ¦  «        cxk    rdk    rn ndt          |¦  «        cxk    rdk    sn t          d¦  «        ‚d„ |                     ¦   «         D ¦   «         }|r+t	          d„ |                     ¦   «         D ¦   «         ¦  «        rt          d¦  «        ‚t          ¦   «         5 }|                     d	¦  «         t          j	        d
¦  «         
                    ¦   «         }|                     d|| |f¦  «        }|                     ¦   «         D ]V\  }}|                     d|||f¦  «        }	|	j        dk    rt          d¦  «        ‚|                     d|j        ||f¦  «         ŒW	 d d d ¦  «         n# 1 swxY w Y   |S )Nr7   éx   é   éÈ   z1Bitte Name und E-Mail oder Telefonnummer angeben.c                 ót   — i | ]5\  }}t          |¦  «        d k    ¯t          |¦  «        t          |¦  «        “Œ6S )r   )Úint)r9   ÚkÚvs      r   ú
<dictcomp>zreserve.<locals>.<dictcomp>Z   s5   € ÐKÐKÐK¡  A½sÀ1¹v¼vÈº{¸{�c�!‰fŒf•c˜!‘f”f¸{¸{¸{r   c              3   ó.   K  — | ]}|d k     p|dk    V — ŒdS )r7   i'  Nr8   )r9   rd   s     r   ú	<genexpr>zreserve.<locals>.<genexpr>[   s/   è è € ÐDÐD¨q˜˜QšÐ* ! d¢(ÐDÐDÐDÐDÐDÐDr   u7   Bitte mindestens einen verfÃ¼gbaren Artikel auswÃ¤hlen.úBEGIN IMMEDIATEé   z?INSERT INTO reservations(reference,name,contact) VALUES (?,?,?)z9UPDATE products SET stock=stock-? WHERE id=? AND stock>=?uS   Der gewÃ¼nschte Bestand ist inzwischen nicht mehr verfÃ¼gbar. Bitte neu auswÃ¤hlen.z INSERT INTO items VALUES (?,?,?))ÚstriprV   rW   ÚitemsÚanyÚvaluesr,   r0   rX   rY   ÚupperÚrowcountÚ	lastrowid)
ÚnameÚcontactÚ
quantitiesÚchosenr1   ÚrefÚcurÚpidÚqtyÚupdateds
             r   Úreserverz   V   s  € Ø—J’J‘L”L '§-¢-¡/¤/ˆ'€DØ•�D‘	”	Ð Ð Ò Ð ˜SÒ Ð Ð Ð Ð ¨­S°©\¬\Ð(@Ð(@Ò(@Ð(@¸SÒ(@Ð(@Ð(@Ð(@ÝÐLÑMÔMÐMØKÐK¨×)9Ò)9Ñ);Ô);ÐKÑKÔK€FØð T•SÐDÐD°F·M²M±O´OÐDÑDÔDÑDÔDð TÝÐRÑSÔSÐSÝ	‰Œð V�bØ
�
Š
Ð$Ñ%Ô%Ð%ÝÔ Ñ"Ô"×(Ò(Ñ*Ô*ˆØ�jŠjÐZÐ]`ÐbfÐhoÐ\pÑqÔqˆØŸš™œð 	Vð 	V‰HˆC�Ø—j’jÐ!\Ð_bÐdgÐilÐ^mÑnÔnˆGØÔ 1Ò$Ð$Ý Ð!vÑwÔwÐwØ�JŠJÐ9¸C¼MÈ3ÐPSÐ;TÑUÔUÐUÐUð		Vð	Vð Vð Vñ Vô Vð Vð Vð Vð Vð Vð Vøøøð Vð Vð Vð Vð €Js   ÃC F&Æ&F*Æ-F*c                 ó6  — |dvrt          d¦  «        ‚t          ¦   «         5 }|                     d¦  «         |                     d| f¦  «                             ¦   «         }|st          d¦  «        ‚|d         |k    r	 d d d ¦  «         d S |d         dv rt          d¦  «        ‚|d	k    r>|                     d
| f¦  «        D ]&}|                     d|d         |d         f¦  «         Œ'|                     d|| f¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )N©Úoffenõ
   bestÃ¤tigtÚabgeholtÚ	storniertu   UngÃ¼ltiger Status.rh   ú*SELECT status FROM reservations WHERE id=?úReservierung nicht gefunden.Ústatus©r   r€   uD   Abgeschlossene Reservierungen kÃ¶nnen nicht erneut geÃ¶ffnet werden.r€   ú*SELECT * FROM items WHERE reservation_id=?ú,UPDATE products SET stock=stock+? WHERE id=?ÚquantityÚ
product_idz+UPDATE reservations SET status=? WHERE id=?)rW   r,   r0   Úfetchone)Úridrƒ   r1   ÚoldÚitems        r   Úchange_statusr�   i   s¼  € ØÐEÐEÐEÝÐ.Ñ/Ô/Ð/Ý	‰Œð Q�bØ
�
Š
Ð$Ñ%Ô%Ð%Ø�jŠjÐEÈÀvÑNÔN×WÒWÑYÔYˆØð 	=ÝÐ;Ñ<Ô<Ð<ØˆxŒ=˜FÒ"Ð"ØðQð Qð Qñ Qô Qð Qð Qð Qð ˆxŒ=Ð5Ð5Ð5ÝÐcÑdÔdÐdØ�[Ò Ð ØŸ
š
Ð#OÐRUÐQWÑXÔXð sð s�Ø—
’
ÐIÈDÐQ[ÔL\Ð^bÐcoÔ^pÐKqÑrÔrÐrÐrØ
�
Š
Ð@À6È3À-ÑPÔPÐPðQð Qð Qñ Qô Qð Qð Qð Qð Qð Qð Qð Qøøøð Qð Qð Qð Qð Qð Qs   ¢ADÂA5DÄDÄDc                 óª  — t          ¦   «         5 }|                     d¦  «         |                     d| f¦  «                             ¦   «         }|st          d¦  «        ‚|                     d| f¦  «                             ¦   «         d         }|rt          d¦  «        ‚|                     d| f¦  «         d d d ¦  «         n# 1 swxY w Y   |d         S )	Nrh   ú%SELECT image FROM products WHERE id=?úArtikel nicht gefunden.z-SELECT count(*) FROM items WHERE product_id=?r   uK   Dieser Artikel steckt noch in Reservierungen. Zuerst die Anfragen lÃ¶schen.zDELETE FROM products WHERE id=?r<   ©r,   r0   r‰   rW   )rw   r1   r:   Úuseds       r   Údelete_productr“   {   s  € Ý	‰Œð >�bØ
�
Š
Ð$Ñ%Ô%Ð%Ø�jŠjÐ@À3À&ÑIÔI×RÒRÑTÔTˆØð 	8ÝÐ6Ñ7Ô7Ð7Ø�zŠzÐIÈCÈ6ÑRÔR×[Ò[Ñ]Ô]Ð^_Ô`ˆØð 	lÝÐjÑkÔkÐkØ
�
Š
Ð4°s°fÑ=Ô=Ð=ð>ð >ð >ñ >ô >ð >ð >ð >ð >ð >ð >øøøð >ð >ð >ð >ð ˆwŒ<Ðs   �B'CÃCÃ	Cc                 óÞ  — t          ¦   «         5 }|                     d¦  «         |                     d| f¦  «                             ¦   «         }|st          d¦  «        ‚|d         dv r>|                     d| f¦  «        D ]&}|                     d|d         |d	         f¦  «         Œ'|                     d
| f¦  «         |                     d| f¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )Nrh   r�   r‚   rƒ   ©r}   r~   r…   r†   r‡   rˆ   z(DELETE FROM items WHERE reservation_id=?z#DELETE FROM reservations WHERE id=?r‘   )rŠ   r1   r‹   rŒ   s       r   Údelete_reservationr–   ˆ   sX  € Ý	‰Œð 	B�bØ
�
Š
Ð$Ñ%Ô%Ð%Ø�jŠjÐEÈÀvÑNÔN×WÒWÑYÔYˆØð 	=ÝÐ;Ñ<Ô<Ð<ØˆxŒ=Ð3Ð3Ð3ØŸ
š
Ð#OÐRUÐQWÑXÔXð sð s�Ø—
’
ÐIÈDÐQ[ÔL\Ð^bÐcoÔ^pÐKqÑrÔrÐrÐrØ
�
Š
Ð=À¸vÑFÔFÐFØ
�
Š
Ð8¸3¸&ÑAÔAÐAð	Bð 	Bð 	Bñ 	Bô 	Bð 	Bð 	Bð 	Bð 	Bð 	Bð 	Bð 	Bøøøð 	Bð 	Bð 	Bð 	Bð 	Bð 	Bs   �CC"Ã"C&Ã)C&c                 óH   — t          j        t          | ¦  «        d¬¦  «        S )NT)Úquote)ÚhtmlÚescapeÚstr)Úvalues    r   Úescr�   •   s   € ÝŒ;•s˜5‘z”z¨Ð.Ñ.Ô.Ð.r   c                 ó   — |                       d¦  «        rdS |                       d¦  «        rdS |                       d¦  «        rdS t          | ¦  «        dk    r%|                       d¦  «        r| d	d…         d
k    rdS d S )Ns   ÿØÿr   s   ‰PNG

r   )s   GIF87as   GIF89ar   rT   s   RIFFrF   s   WEBPr   )r   rV   )r   s    r   Ú
image_kindrŸ   ™   sŠ   € Ø‡‚�Ñ'Ô'ð ØˆuØ‡‚Ð+Ñ,Ô,ð ØˆuØ‡‚Ð-Ñ.Ô.ð ØˆuÝ
ˆ4�y„y�B‚€˜4Ÿ?š?¨7Ñ3Ô3€¸¸Q¸r¸T¼
ÀgÒ8MÐ8MØˆvØˆ4r   c                 óT  — | r"t          | ¦  «                             d¦  «        rd S t          j        d| ¦  «        sd S t          | z                       ¦   «         }|j        t                               ¦   «         k    r*|                     ¦   «         r|                     ¦   «          d S d S d S )Nú	beispiel:ú [0-9a-f]{32}\.(jpg|png|gif|webp))	r›   r   ÚreÚ	fullmatchÚUPLOADSÚresolver>   Úis_fileÚunlink)Úkeyr   s     r   Údrop_uploadrª   ¥   sœ   € Øð •#�c‘(”(×%Ò% kÑ2Ô2ð ØˆÝŒ<Ð;¸SÑAÔAð ØˆÝ�c‰M×"Ò"Ñ$Ô$€DØ„{•g—o’oÑ'Ô'Ò'Ð'¨D¯LªL©N¬NÐ'Ø�Š‰Œˆˆˆð (Ð'Ð'Ð'r   c                 óX  — |r¯t          |¦  «        }|r!dt          |¦  «        cxk    rt          k    sn t          d¦  «        ‚t                               dd¬¦  «         t          j        d¦  «        dz   |z   }t          |z  }|                     |¦  «         | 	                    d¦  «         || fS |dk    rd	| fS | 
                    d
¦  «        rW|                     dd¦  «        d         }|t          vst          |z                       ¦   «         st          d¦  «        ‚d
|z   | fS | d	fS )uM   Neues Bild speichern. Gibt (schlÃ¼ssel, zu lÃ¶schendes altes Upload) zurÃ¼ck.é    z?Bitte ein Bild als JPEG, PNG, WEBP oder GIF bis 2 MB verwenden.Tr3   rU   ú.r=   r[   Nr¡   ú:r7   zBeispielbild nicht gefunden.)rŸ   rV   Ú	MAX_IMAGErW   r¥   r?   rX   rY   Úwrite_bytesrA   r   ÚsplitÚEXAMPLESÚEXAMPLES_DIRr§   )ÚpreviousÚchoiceÚuploadÚkindrq   r   Úfnames          r   Ústore_imager¹   ¯   sI  € àð 	Ý˜&Ñ!Ô!ˆØð 	`˜2¥ V¡¤Ð9Ð9Ò9Ð9µ	Ò9Ð9Ð9Ð9ÝÐ^Ñ_Ô_Ð_Ý�Š˜d¨TˆÑ2Ô2Ð2ÝÔ  Ñ$Ô$ sÑ*¨TÑ1ˆÝ˜‰~ˆØ×Ò˜Ñ Ô Ð Ø�
Š
�5ÑÔÐØ�Xˆ~ÐØ�ÒÐØ�Xˆ~ÐØ×Ò˜Ñ%Ô%ð -Ø—’˜S !Ñ$Ô$ QÔ'ˆØ�Ð Ð ­¸Ñ)=×(FÒ(FÑ(HÔ(HÐ ÝÐ;Ñ<Ô<Ð<Ø˜UÑ" HÐ,Ð,Ø�Tˆ>Ðr   c                 ó"  — | sd S t          | ¦  «                             d¦  «        r}|                      dd¦  «        d         }|t          vrd S t          |z                       ¦   «         }|j        t                               ¦   «         k    s|                     ¦   «         sd S |S t          j	        d| ¦  «        sd S t          | z                       ¦   «         }|j        t                               ¦   «         k    s|                     ¦   «         sd S |S )Nr¡   r®   r7   r¢   )r›   r   r±   r²   r³   r¦   r>   r§   r£   r¤   r¥   )r©   rq   r   s      r   Ú
image_pathr»   Å   sö   € Øð ØˆtÝ
ˆ3�x„x×Ò˜;Ñ'Ô'ð Ø�yŠy˜˜aÑ Ô  Ô#ˆØ•xÐÐØ�4Ý˜tÑ#×,Ò,Ñ.Ô.ˆØŒ;�,×.Ò.Ñ0Ô0Ò0Ð0¸¿º¹¼Ð0Ø�4ØˆÝŒ<Ð;¸SÑAÔAð ØˆtÝ�c‰M×"Ò"Ñ$Ô$€DØ„{•g—o’oÑ'Ô'Ò'Ð'¨t¯|ª|©~¬~Ð'ØˆtØ€Kr   c                 óX  — t          j        d|¦  «        }|st          d¦  «        ‚d|                     d¦  «        p|                     d¦  «                             dd¦  «        z   }i d |                      |¦  «        df\  }}}}|dk     rt          d¦  «        ‚|t          |¦  «        z  }|d	k     �rt| ||dz   …         dk    r�na| ||dz   …         d
k    rt          d¦  «        ‚|dz  }|                      d|¦  «        }|dk    r|                      d
|z   |dz   ¦  «        nd}	|dk     s|	dk     rt          d¦  «        ‚| ||…                              dd¦  «        }
| |dz   |	…         }|	dz   t          |¦  «        z   }|dz  }t          j        d|
¦  «        }|r&t          |                     d¦  «        ¦  «        dk    r�Œt          j        d|
¦  «        }|r|                     d¦  «        r|r|}n+|                     d¦  «        ||                     d¦  «        <   |d	k     �°t||fS )Nz boundary=(?:"([^"]+)"|([^;\s]+))õ   UngÃ¼ltige Anfrage.s   --r7   é   ÚasciiÚstrictr   é   s   
s   

é   éÿÿÿÿzlatin-1Úreplacezname="([^"]+)"é(   zfilename="([^"]*)"úutf-8)r£   ÚsearchrW   ÚgrouprM   ÚfindrV   Údecode)ÚbodyÚcontent_typeÚmatchÚmarkerÚfieldsr¶   ÚposÚpartsÚendÚnxtÚheaderÚcontentrq   Úfilenames                 r   Úparse_multipartr×   Ø   sP  € ÝŒIÐ9¸<ÑHÔH€EØð 0ÝÐ.Ñ/Ô/Ð/Ø�e—k’k !‘n”nÐ6¨¯ª°A©¬×>Ò>¸wÈÑQÔQÑQ€FØ!# T¨4¯9ª9°VÑ+<Ô+<¸aÐ!?Ñ€FˆF�C˜Ø
ˆQ‚w€wÝÐ.Ñ/Ô/Ð/Ø�3ˆv‰;Œ;Ñ€CØ
�"Š*‰*Ø��C˜!‘G�Ô Ò%Ð%ÙØ��C˜!‘G�Ô Ò'Ð'ÝÐ2Ñ3Ô3Ð3Øˆq‰ˆØ�iŠi˜ SÑ)Ô)ˆØ69¸Q²h°hˆd�iŠi˜ &Ñ(¨#°©'Ñ2Ô2Ð2ÀBˆØ�Š7ˆ7�c˜A’g�gÝÐ2Ñ3Ô3Ð3Ø�c˜#�g”×%Ò% i°Ñ;Ô;ˆØ�s˜Q‘w˜s�{Ô#ˆØ�A‰g�˜F™œÑ#ˆØ�‰
ˆÝŒyÐ*¨FÑ3Ô3ˆØð 	•s˜4Ÿ:š: a™=œ=Ñ)Ô)¨BÒ.Ð.ÙÝ”9Ð2°FÑ;Ô;ˆØð 	<Ø�~Š~˜aÑ Ô ð ! Wð !Ø �øà$+§N¢N°7Ñ$;Ô$;ˆF�4—:’:˜a‘=”=Ñ!ð- �"Š*‰*ð. �6ˆ>Ðr   a  *{box-sizing:border-box}body{margin:0;background:#f5f3eb;color:#21382a;font:17px system-ui,sans-serif}header,main,footer{max-width:1050px;margin:auto;padding:24px}header{display:flex;justify-content:space-between;align-items:center}a{color:#385c3b}h1{font: bold clamp(34px,6vw,62px) Georgia,serif;line-height:1.1;margin:20px 0}h2{font-family:Georgia,serif}p{line-height:1.6}.hero{padding:28px 0 40px;max-width:720px}.eyebrow{letter-spacing:.15em;text-transform:uppercase;font-size:13px}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:18px}.card{background:white;padding:24px;border:1px solid #d5ddcf;border-radius:14px;margin-bottom:18px}label{display:block;margin:12px 0}input,textarea,select,button{font:inherit;padding:11px;border:1px solid #bcc8b7;border-radius:7px;width:100%}input[type=radio],input[type=checkbox]{width:auto}input[type=number]{max-width:160px}button{background:#294e35;color:white;cursor:pointer;margin-top:12px}.danger{background:#8a3b2a}nav{display:flex;gap:18px}.muted,small{color:#566555}.notice{padding:18px;background:#e4ecd9;border-radius:10px}.error{background:#f9dfd5}.row{display:flex;gap:20px;flex-wrap:wrap}.row>*{flex:1;min-width:200px}footer{font-size:14px;border-top:1px solid #d5ddcf}.cut{width:100%;height:190px;object-fit:cover;border-radius:10px;display:block;margin-bottom:12px}.picks{display:flex;flex-wrap:wrap;gap:12px}.picks label{width:148px;font-size:14px}.picks img{width:100%;height:96px;object-fit:cover;border-radius:8px}fieldset{border:0;padding:0;margin:12px 0}c                   óX   — e Zd Zd„ Zd„ Zd„ Zd„ Zdd„Zd„ Zd„ Z	d	„ Z
d
„ Zd„ Zd„ Zd„ ZdS )ÚHandlerc                 ó   — d S r   r8   )r    r!   s     r   Úlog_messagezHandler.log_messageÿ   s   € Øˆr   c                 ó`  — t          j        ¦   «         }	 |                     | j                             dd¦  «        ¦  «         d|v r|d         j        nd}n# t           j        $ r d}Y nw xY wt          j        ¦   «         }t          t          ¦  «        D ]4}t          |         d         |k     rt           
                    |d ¦  «         Œ5t                               |¦  «        }|€9t          j        d¦  «        }t          j        d¦  «        d|dz   dœ}|t          |<   ||c| _        | _        d S )	NÚCookier
   ÚsessionÚexpiresr¬   Fé  ©ÚcsrfÚadminrß   )r   ÚSimpleCookieÚloadÚheadersÚgetrœ   ÚCookieErrorÚtimeÚlistrZ   ÚpoprX   Útoken_urlsafeÚsidÚsess)r    Újarrí   Únowr©   rÞ   s         r   rÞ   zHandler.session  s*  € ÝÔ"Ñ$Ô$ˆð	Ø�HŠH�T”\×%Ò% h°Ñ3Ô3Ñ4Ô4Ð4Ø*3°sÐ*:Ð*:�#�i”.Ô&Ð&ÀˆCˆCøÝÔ"ð 	ð 	ð 	ØˆCˆCˆCð	øøøåŒi‰kŒkˆÝ�‘>”>ð 	(ð 	(ˆCÝ˜Œ}˜YÔ'¨#Ò-Ð-Ý—’˜S $Ñ'Ô'Ð'øÝ—,’,˜sÑ#Ô#ˆØˆ?ÝÔ'¨Ñ+Ô+ˆCÝ&Ô4°RÑ8Ô8À5ÐUXÐ[_ÑU_Ð`Ð`ˆGØ#�H�S‰MØ! 7ÐˆŒ�$”)�)�)s   •AA ÁA+Á*A+c                 óô   — | j                              dd¦  «                             d¦  «        d                              ¦   «                              ¦   «         }|dk    rdnd}d| j        › dt          pd	› d
|› �S )NzX-Forwarded-Protor
   ú,r   Úhttpsz; Securezsession=z"; HttpOnly; SameSite=Strict; Path=r   z; Max-Age=3600)ræ   rç   r±   rj   Úlowerrí   r   )r    Ú	forwardedÚsecures      r   ÚcookiezHandler.cookie  s}   € Ø”L×$Ò$Ð%8¸"Ñ=Ô=×CÒCÀCÑHÔHÈÔK×QÒQÑSÔS×YÒYÑ[Ô[ˆ	Ø(¨GÒ3Ð3��¸ˆØi˜$œ(ÐiÐiÅdÀkÈcÐiÐiÐagÐiÐiÐir   c                 ó  — | j                              dd¦  «        d         }t          s|S |t          k    s|t          dz   k    rdS |                     t          dz   ¦  «        r|t	          t          ¦  «        d …         pdS d S )Nú?r7   r   r   )r   r±   r   r   rV   ©r    r   s     r   ÚroutezHandler.route  s|   € ØŒy�Š˜s AÑ&Ô& qÔ)ˆÝð 	ØˆKØ•4Š<ˆ<˜4¥4¨#¡:Ò-Ð-Ø�3Ø�?Š?�4 #™:Ñ&Ô&ð 	+Ø��D™	œ	˜
˜
Ô#Ð* sÐ*Øˆtr   r`   c                 ó¤  — dt           z   dt          d¦  «        › dt          d¦  «        › d�z   |z   dz                        ¦   «         }|                      |¦  «         |                      dd	¦  «         |                      d
t          t          |¦  «        ¦  «        ¦  «         |                      d|                      ¦   «         ¦  «         |                      dd¦  «         |                      dd¦  «         |                      dd¦  «         |                      dd¦  «         |                      ¦   «          | j	         
                    |¦  «         d S )Nu³   <!doctype html><html lang="de"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Wildfleisch Â· Bestand & Reservierung</title><style>z:</style><header><strong>WALD & WILD</strong><nav><a href="r   z">Bestand</a><a href="ú/adminz%">Verwaltung</a></nav></header><main>u…   </main><footer>Reservierungsanfrage Â· Kein verbindlicher Kauf Â· Abholung und Details nach persÃ¶nlicher Abstimmung.</footer></html>úContent-Typeztext/html; charset=utf-8úContent-Lengthú
Set-CookieúCache-Controlzno-storeúX-Content-Type-OptionsÚnosniffzX-Frame-OptionsÚDENYzContent-Security-Policyzzdefault-src 'none'; img-src 'self'; style-src 'unsafe-inline'; form-action 'self'; frame-ancestors 'none'; base-uri 'none')ÚSTYLEr   rM   Úsend_responseÚsend_headerr›   rV   r÷   Úend_headersÚwfileÚwrite)r    rÕ   rƒ   rË   s       r   Ú	send_pagezHandler.send_page#  s³  € ð Kõ  NSñ  Sð  Vgõ  UVð  WZñ  U[ô  U[ð  Vgð  Vgõ  stð  u}ñ  s~ô  s~ð  Vgð  Vgð  Vgñ  gð  jqñ  qð  tñ  ÷  Gò  Gñ  Iô  IˆØ×Ò˜6Ñ"Ô"Ð"Ø×Ò˜Ð)CÑDÔDÐDØ×ÒÐ)­3­s°4©y¬y©>¬>Ñ:Ô:Ð:Ø×Ò˜ t§{¢{¡}¤}Ñ5Ô5Ð5Ø×Ò˜¨*Ñ5Ô5Ð5Ø×ÒÐ1°9Ñ=Ô=Ð=Ø×ÒÐ*¨FÑ3Ô3Ð3Ø×ÒÐ2ð  5qñ  	rô  	rð  	rØ×ÒÑÔÐØŒ
×Ò˜ÑÔÐÐÐr   c                 ó$   — d| j         d         › d�S )Nz(<input type="hidden" name="csrf" value="râ   ú">)rî   )r    s    r   ÚtokenzHandler.token0  s   € ØO¸$¼)ÀFÔ:KÐOÐOÐOÐOr   c                 ó  — |                       d¦  «         |                      dt          |¦  «        ¦  «         |                      d|                      ¦   «         ¦  «         |                      dd¦  «         |                      ¦   «          d S )Ni/  ÚLocationr   rÿ   Ú0)r  r  r   r÷   r  rú   s     r   ÚredirectzHandler.redirect3  s   € Ø×Ò˜3ÑÔÐØ×Ò˜¥Q t¡W¤WÑ-Ô-Ð-Ø×Ò˜ t§{¢{¡}¤}Ñ5Ô5Ð5Ø×ÒÐ)¨3Ñ/Ô/Ð/Ø×ÒÑÔÐÐÐr   c                 óp  — |                       d¦  «         |                      d|¦  «         |                      dt          t          |¦  «        ¦  «        ¦  «         |                      dd¦  «         |                      dd¦  «         |                      ¦   «          | j                             |¦  «         d S )Nr`   rþ   rÿ   r  r  r  zprivate, max-age=3600)r  r  r›   rV   r  r	  r
  )r    r   Úmimes      r   Ú
send_byteszHandler.send_bytes:  s«   € Ø×Ò˜3ÑÔÐØ×Ò˜¨Ñ.Ô.Ð.Ø×ÒÐ)­3­s°4©y¬y©>¬>Ñ:Ô:Ð:Ø×ÒÐ1°9Ñ=Ô=Ð=Ø×Ò˜Ð*AÑBÔBÐBØ×ÒÑÔÐØŒ
×Ò˜ÑÔÐÐÐr   c                 ó  — t          |¦  «        }|€|                      dd¦  «         d S |                     ¦   «         }t          |¦  «        }|s|                      dd¦  «         d S |                      |t
          |         ¦  «         d S )Nz<h1>Bild nicht gefunden</h1>é”  )r»   r  Ú
read_bytesrŸ   r  ÚIMAGE_TYPES)r    r©   r   r   r·   s        r   Úsend_stored_imagezHandler.send_stored_imageC  s‰   € Ý˜#‰ŒˆØˆ<Ø�NŠNÐ9¸3Ñ?Ô?Ð?ØˆFØ�ŠÑ Ô ˆÝ˜$ÑÔˆØð 	Ø�NŠNÐ9¸3Ñ?Ô?Ð?ØˆFØ�Š˜�k¨$Ô/Ñ0Ô0Ð0Ð0Ð0r   c                 ó  — |                       ¦   «          |                      ¦   «         }|rQ|                     d¦  «        r<|t          d¦  «        d …         }|                      |t
          v rd|z   nd ¦  «         d S |r¿|                     d¦  «        rª|t          d¦  «        d …         }d }|                     ¦   «         r\t          ¦   «         5 }|                     dt          |¦  «        f¦  «         
                    ¦   «         }d d d ¦  «         n# 1 swxY w Y   |                      |r|d         nd ¦  «         d S |dk    �ryt          ¦   «         5 }|                     d¦  «                             ¦   «         }d d d ¦  «         n# 1 swxY w Y   d}|D ]Ý}|d         rUd	t          dt          |d
         ¦  «        z   ¦  «        › dt          |d         ¦  «        › dt          |d         ¦  «        › d�nd}	|d|	› dt          |d         ¦  «        › dt          |d         ¦  «        › d|d         › dt          |d         ¦  «        › dt          |d         ¦  «        › d|d
         › d|d         › d�z  }ŒÞ|sd}|                      dt          d¦  «        › d�|                      ¦   «         z   dz   |z   d z   ¦  «         d S |d!k    r|                      ¦   «          d S |                      d"t          d¦  «        › d#�d$¦  «         d S )%Nú
/beispiel/r¡   ú/bild/r�   r<   r   ú$SELECT * FROM products ORDER BY namer
   ú<img class="cut" src="Úidú?v=z" alt="rq   r  z<article class="card">z<h2>ú</h2><p>Údescriptionz</p><p><strong>Ústockú Úunitu&    verfÃ¼gbar</strong></p><label>Menge (z)<input type="number" name="q_z" min="0" max="z" value="0"></label></article>zZ<p class="notice">Aktuell ist noch kein Bestand eingestellt. Schau bald wieder vorbei.</p>u  <section class="hero"><span class="eyebrow">Wildfleisch aus dem aktuellen Bestand</span><h1>Gutes Wild.<br>Einfach reservieren.</h1><p>WÃ¤hle deine gewÃ¼nschten Portionen aus. Wir halten sie fÃ¼r dich zurÃ¼ck und stimmen alle Details persÃ¶nlich ab.</p></section><form action="ú/reservez" method="post">z<div class="grid">a[  </div><section class="card"><h2>Deine Reservierungsanfrage</h2><p>Eine Einheit entspricht der angegebenen Portion oder Packung. Es entstehen hier weder Kaufvertrag noch Zahlungspflicht.</p><div class="row"><label>Dein Name<input name="name" required maxlength="120" autocomplete="name"></label><label>E-Mail oder Telefonnummer<input name="contact" required minlength="3" maxlength="200"></label></div><p class="muted">Deine Angaben werden lokal zur Bearbeitung der Anfrage gespeichert und sind nur in der Verwaltung sichtbar.</p><button>Anfrage absenden und Bestand reservieren</button></section></form>rý   z&<h1>Seite nicht gefunden</h1><a href="z">Zum Bestand</a>r  )rÞ   rû   r   rV   r  r²   Úisdigitr,   r0   rb   r‰   Úfetchallr   r›   r�   r  r  Ú
admin_page)
r    r   rq   Úidentr:   r1   ÚproductsÚcardsrJ   Úphotos
             r   Údo_GETzHandler.do_GETO  sÊ  € Ø�Š‰ŒˆØ�zŠz‰|Œ|ˆØð 	�D—O’O LÑ1Ô1ð 	Ø�˜LÑ)Ô)Ð*Ð*Ô+ˆDØ×"Ò"¸ÅÐ9IÐ9I ;°Ñ#5Ð#5ÈtÑTÔTÐTØˆFØð 	�D—O’O HÑ-Ô-ð 	Ø�˜X™œ˜˜Ô(ˆEØˆCØ�}Š}‰Œð hÝ‘Y”Yð h "ØŸ*š*Ð%LÍsÐSXÉzÌzÈmÑ\Ô\×eÒeÑgÔg�Cðhð hð hñ hô hð hð hð hð hð hð høøøð hð hð hð hà×"Ò"°3Ð#@ 3 w¤< <¸DÑAÔAÐAØˆFØ�3Š;‰;Ý‘”ð Y˜bØŸ:š:Ð&LÑMÔM×VÒVÑXÔX�ðYð Yð Yñ Yô Yð Yð Yð Yð Yð Yð Yøøøð Yð Yð Yð YàˆEØð oð o�Ø~ð  AHô  Ið  QÐzµ°8½cÀ!ÀDÄ'¹l¼lÑ3JÑ1KÔ1KÐzÐzÕPSÐTUÐV]ÔT^ÑP_ÔP_ÐzÐzÕhkÐlmÐntÔluÑhvÔhvÐzÐzÐzÐzð  OQ�Øð  o°%ð  oð  o½SÀÀ6Ä¹^¼^ð  oð  oÕUXÐYZÐ[hÔYiÑUjÔUjð  oð  oÐ{|ð  ~Eô  |Fð  oð  oõ  ILð  MNð  OUô  MVñ  IWô  IWð  oð  oõ  Bð  CDð  EKô  CLñ  Mô  Mð  oð  oð  mnð  osô  mtð  oð  oð  EFð  GNô  EOð  oð  oð  oñ  o��Øð uØt�Ø�NŠNð  Sõ  tuð  v@ñ  tAô  tAð  Sð  Sð  Sð  VZ÷  V`ò  V`ñ  Vbô  Vbñ  bð  eyñ  yð  |Añ  Að  Dañ  añ  bô  bð  bð  bð  bØ�XÒÐØ�OŠOÑÔÐÐÐà�NŠNÐ]ÅAÀcÁFÄFÐ]Ð]Ð]Ð_bÑcÔcÐcÐcÐcs$   Ã7DÄDÄDÅ(FÆF
ÆF
c                 ó	  ‡— | j         d         s@|                      dt          d¦  «        › d�|                      ¦   «         z   dz   ¦  «         d S t	          ¦   «         5 }|                     d¦  «                             ¦   «         }|                     d¦  «                             ¦   «         }|                     d¦  «                             ¦   «         }d d d ¦  «         n# 1 swxY w Y   d	t          d
¦  «        › d�|                      ¦   «         z   dz   }d g|z   D �]Â}|r|d         nd }|dt          d¦  «        › d�|                      ¦   «         z   d|r|d         nd› d|rdnd› d�z   z  }dD ]9\  }}	}
|r||         n|
}|d|	› d|› dt          |¦  «        › d|dk    rdnd› d�	z  }Œ:|d z  }|r<|d!t          d"t          |d         ¦  «        z   ¦  «        › d#t          |¦  «        › d$�z  }|o!t          |¦  «         	                    d%¦  «         }|d&|rd'nd› d(|rd)nd*› d+�z  }|r|d,z  }|d-z  }t                               ¦   «         D ]N\  }}	|d%|z   k    }|d.t          |¦  «        › d/|rd'nd› d0t          d1|z   ¦  «        › d2t          |	¦  «        › d3�	z  }ŒO|d4z  }|d5z  }|r8|dt          d6¦  «        › d�|                      ¦   «         z   d|d         › d7�z   z  }�ŒÄ|d8z  }|s|d9z  }|D �]{Š|d:t          ‰d;         ¦  «        › d<t          ‰d=         ¦  «        › d>t          ‰d?         ¦  «        › d@t          ‰dA         ¦  «        › dBt          ‰dC         ¦  «        › dD�z  }|D ]O}|dE         ‰d         k    r;|dF|dG         › dHt          |dI         ¦  «        › dHt          |d=         ¦  «        › dJ�z  }ŒP|dKz  }‰dC         dLvrY|dMt          dN¦  «        › d|                      ¦   «         › d‰d         › dO�d                     ˆfdP„dQD ¦   «         ¦  «        z   dRz   z  }‰dC         dSv rdTndU}|dMt          dV¦  «        › d|                      ¦   «         › d‰d         › dW|› dX�	z  }|dYz  }�Œ}|                      |¦  «         d S )ZNrã   z<<h1>Verwaltung</h1><form class="card" method="post" action="ú/loginr  z�<label>Admin-Passwort<input name="password" type="password" required autocomplete="current-password"></label><button>Anmelden</button></form>r  z+SELECT * FROM reservations ORDER BY id DESCzJSELECT i.*,p.name,p.unit FROM items i JOIN products p ON p.id=i.product_idz7<h1>Bestand & Anfragen</h1><form method="post" action="ú/logoutu™   <button>Abmelden</button></form><h2>Bestand pflegen</h2><p>Bestand ist die noch frei verfÃ¼gbare Menge. Reservierte Einheiten sind bereits abgezogen.</p>r<   z)<form class="card" method="post" action="ú/productz " enctype="multipart/form-data">z&<input type="hidden" name="id" value="r   r
   z"><h2>zArtikel bearbeitenzNeuer Artikelz</h2>))rq   ÚBezeichnungr
   )r#  u   Beschreibung / PackungsgrÃ¶ÃŸer
   )r&  u    Einheit (z. B. Packung Ã  500 g)Ú	Packungen)r$  u   Frei verfÃ¼gbare Einheitenr  z<label>z<input name="z	" value="z" r$  ztype=number min=0 max=999999zmaxlength=500z required></label>z<fieldset><legend>Bild</legend>r  r  r!  z	" alt="">r¡   z;<label><input type="radio" name="image_choice" value="keep"z checkedz> zAktuelles Bild behaltenz	Ohne Bildz</label>zT<label><input type="radio" name="image_choice" value="clear"> Bild entfernen</label>z<div class="picks">z?<label><input type="radio" name="image_choice" value="beispiel:ú"z><img src="r  z" alt=""><span>z</span></label>u?  </div><label>Eigenes Bild hochladen, hat Vorrang vor der Auswahl<input type="file" name="image" accept="image/jpeg,image/png,image/webp,image/gif"></label><p class="muted">JPEG, PNG, WEBP oder GIF, hÃ¶chstens 2 MB. Die Beispielbilder zeigen typische Zuschnitte und sind nicht das Foto der konkreten Ware.</p></fieldset>z!<button>Speichern</button></form>ú/product-deleteuó   "><label><input type="checkbox" name="confirm" value="1" required> Artikel unwiderruflich lÃ¶schen</label><button class="danger">Artikel lÃ¶schen</button><p class="muted">Geht nur, solange keine Reservierung diesen Artikel enthÃ¤lt.</p></form>z<h2>Reservierungen</h2>z<p>Noch keine Anfragen.</p>z<section class="card"><h2>Ú	referencer"  rq   u    Â· rr   z</p><p>Úcreatedu    UTC Â· <strong>rƒ   z</strong></p><ul>Úreservation_idz<li>r‡   r%  r&  z</li>z</ul>r„   z<form method="post" action="ú/statusz%"><label>Status<select name="status">c              3   óF   •K  — | ]}d |‰d         k    rdnd› d|› d�V — ŒdS )z<option rƒ   Úselectedr
   ú>z	</option>Nr8   )r9   ÚsrI   s     €r   rg   z%Handler.admin_page.<locals>.<genexpr>•  s¶   øè è € ð  wpð  wpð  }~ð  xxð  QRð  VWð  X`ô  Vaò  Qað  Qað  CMð  CMð  gið  xxð  xxð  lmð  xxð  xxð  xxð  wpð  wpð  wpð  wpð  wpð  wpr   r|   z9</select></label><button>Status speichern</button></form>r•   u:   Offene und bestÃ¤tigte Anfragen geben den Bestand zurÃ¼ck.u    Der Bestand bleibt unverÃ¤ndert.ú/reservation-deleteu«   "><label><input type="checkbox" name="confirm" value="1" required> Anfrage unwiderruflich lÃ¶schen</label><button class="danger">Anfrage lÃ¶schen</button><p class="muted">z</p></form>z
</section>)rî   r  r   r  r,   r0   r)  r�   r›   r   r²   rk   Újoin)r    r1   r,  Úreservationsrk   rÕ   rJ   ÚcurrentÚfieldÚlabelÚdefaultrœ   Úkeepr¸   r=  ÚiÚhintrI   s                    @r   r*  zHandler.admin_pagem  sr  ø€ ØŒy˜Ô!ð 	Ø�NŠNÐiÕZ[Ð\dÑZeÔZeÐiÐiÐiÐlp×lvÒlvÑlxÔlxÑxð  |Kñ  Kñ  Lô  Lð  LØˆFÝ‰YŒYð 	x˜"Ø—z’zÐ"HÑIÔI×RÒRÑTÔTˆHØŸ:š:Ð&SÑTÔT×]Ò]Ñ_Ô_ˆLØ—J’JÐkÑlÔl×uÒuÑwÔwˆEð	xð 	xð 	xñ 	xô 	xð 	xð 	xð 	xð 	xð 	xð 	xøøøð 	xð 	xð 	xð 	xð ]ÍAÈiÉLÌLÐ\Ð\Ð\Ð_c×_iÒ_iÑ_kÔ_kÑkð  oJñ  JˆØ�˜(Ñ"ð 	Wñ 	WˆAØ$%Ð/�a˜”j�j¨4ˆGØÐrÅ1ÀZÁ=Ä=ÐrÐrÐrÐuy×uÒuñ  vBô  vBñ  Bð  Eð  yzð  nBð  noð  ptô  nuð  nuð  @Bð  Eð  Eð  bcð  Jxð  J^ð  J^ð  ixð  Eð  Eð  Eñ  ñ  ˆGð *\ð sð sÑ%��u˜gØ$%Ð2˜˜%œ˜¨7�Øð  s Uð  sð  s¸ð  sð  sÍÈUÉÌð  sð  sÐy~ð  CJò  zJð  zJÐWuÐWuð  P_ð  sð  sð  sñ  s��ØÐ8Ñ8ˆGØð kØÐjµA°hÅÀQÀtÄWÁÄÑ6MÑ4NÔ4NÐjÐjÕSVÐW^ÑS_ÔS_ÐjÐjÐjÑj�ØÐH¥C¨¡L¤L×$;Ò$;¸KÑ$HÔ$HÐIˆDØð  sÐcgÐUoÐU_ÐU_Ðmoð  sð  sð  QXð  tið  tMð  tMð  ^ið  sð  sð  sñ  sˆGØð rØÐqÑq�ØÐ,Ñ,ˆGÝ (§¢Ñ 0Ô 0ð Yð Y‘��uØ" k°EÑ&9Ò9�Øð  YÕ]`ÐafÑ]gÔ]gð  Yð  Yð  yAð  kIÐjtÐjtð  GIð  Yð  Yõ  VWð  Xdð  glñ  Xlñ  Vmô  Vmð  Yð  Yõ  ~Að  BGñ  ~Hô  ~Hð  Yð  Yð  Yñ  Y��Øð  Yñ  YˆGØÐ:Ñ:ˆGØð WØÐ_ÅqÐIZÑG[ÔG[Ð_Ð_Ð_Ðbf×blÒblÑbnÔbnÑnð  rWð  [\ð  ]aô  [bð  rWð  rWð  rWñ  Wñ  W�ùØÐ,Ñ,ˆØð 	5ØÐ4Ñ4ˆGØð 
	$ñ 
	$ˆAØð  FµC¸¸+¼Ñ4GÔ4Gð  Fð  FÕQTÐUVÐW]ÔU^ÑQ_ÔQ_ð  Fð  FÕehÐijÐktÔiuÑevÔevð  Fð  Fõ  @Cð  DEð  FOô  DPñ  @Qô  @Qð  Fð  Fõ  cfð  ghð  iqô  grñ  csô  csð  Fð  Fð  Fñ  FˆGØð ]ð ]�ØÐ%Ô&¨!¨D¬'Ò1Ð1ØÐ\ a¨
¤mÐ\Ð\µc¸!¸F¼)±n´nÐ\Ð\ÅsÈ1ÈVÌ9Á~Ä~Ð\Ð\Ð\Ñ\�GøØ�wÑˆGØ�Œ{Ð":Ð:Ð:Øð  m½!¸I¹,¼,ð  mð  mÈ$Ï*Ê*É,Ì,ð  mð  mÐ~ð  AEô  Fð  mð  mð  mð  pr÷  pwò  pwð  wpð  wpð  wpð  wpð  Boð  wpñ  wpô  wpñ  ppô  ppñ  pð  snñ  nñ  n�ØSTÐU]ÔS^ÐbyÐSyÐSyÐOÐOð  @bˆDØð  LµaÐ8MÑ6NÔ6Nð  Lð  LÐRV×R\ÒR\ÑR^ÔR^ð  Lð  Lð  GHð  IMô  GNð  Lð  Lð  {ð  Lð  Lð  Lñ  LˆGØ�|Ñ#ˆG‰GØ�Š�wÑÔÐÐÐs   ÁA6CÃC#Ã&C#c                 ó   ‡‡— |                       ¦   «          |                      ¦   «         }	 t          | j                             dd¦  «        ¦  «        }| j                             dd¦  «        }d|v }|o|dk    o| j        d         }|dk     s
||rd	nd
k    rt          d¦  «        ‚| j                             |¦  «        }d }|r.|dk    rt          d¦  «        ‚t          ||¦  «        \  Š}ˆfd„}n)t          |                     d¦  «        d¬¦  «        Šˆfd„}t          j         |d¦  «        | j        d         ¦  «        s)|                      dt          d¦  «        › d�d¦  «         d S |dk    �rµ| j        d         }	t#          j        ¦   «         Šˆfd„t$                               |	g ¦  «        D ¦   «         }
t'          |
¦  «        dk    r|                      dd¦  «         d S t)          ¦   «         5 }|                     d¦  «                             ¦   «         }d d d ¦  «         n# 1 swxY w Y   |r8t          j        t/           |d¦  «        |d         ¦  «        |d          ¦  «        s|
‰gz   t$          |	<   t          d!¦  «        ‚t$                               |	d ¦  «         t2                               | j        d ¦  «         t7          j        d"¦  «        | _        t7          j        d"¦  «        d#‰d$z   d%œ| _        | j        t2          | j        <   |                      d&¦  «         d S |d'k    r©i }‰                     ¦   «         D ]D\  }}|                     d(¦  «        r*tA          |tB          ¦  «        r|d         n|||d)d …         <   ŒEtE           |d*¦  «         |d+¦  «        |¦  «        }|                      d,|› d-t          d¦  «        › d.�¦  «         d S |d/v �rB| j        d         s|                      d0d¦  «         d S |d1k    r6t2                               | j        d ¦  «         |                       ¦   «          �nÊ|d2k    r1tG          t           |d3¦  «        ¦  «         |d4¦  «        ¦  «         �n“|d5k    rR |d6¦  «        d7k    rt          d8¦  «        ‚tI          tK          t           |d3¦  «        ¦  «        ¦  «        ¦  «         �n;|d9k    rE |d6¦  «        d7k    rt          d8¦  «        ‚tM          t           |d3¦  «        ¦  «        ¦  «         �nð |d*¦  «         '                    ¦   «          |d:¦  «         '                    ¦   «          |d;¦  «         '                    ¦   «         }}}t           |d<¦  «        ¦  «        }|rO|rM|rKtQ          t'          |¦  «        t'          |¦  «        t'          |¦  «        ¦  «        d=k    sd|cxk    rd>k    sn t          d?¦  «        ‚ |d@¦  «        pdA}t)          ¦   «         5 } |d3¦  «        r�|                     dBt           |d3¦  «        ¦  «        f¦  «                             ¦   «         }|st          dC¦  «        ‚tS          |dD         ||¦  «        \  }}|                     dE|||||t           |d3¦  «        ¦  «        f¦  «         n/tS          d ||¦  «        \  }}|                     dF|||||f¦  «         d d d ¦  «         n# 1 swxY w Y   tI          ||k    r|nd ¦  «         |                      d&¦  «         d S |                      dGdH¦  «         d S # tT          j+        $ r |                      dIdJ¦  «         Y d S t          tX          tT          j-        f$ rR}|                      dKt]          |¦  «        › dLt          d¦  «        › dMt          d&¦  «        › dN�dO¦  «         Y d }~d S d }~ww xY w)PNrÿ   r  rþ   r
   zmultipart/form-datar3  rã   r7   i   rE   u   UngÃ¼ltige AnfragegrÃ¶ÃŸe.r½   c                 ó0   •— ‰                      | d¦  «        S )Nr
   ©rç   ©r©   r   s    €r   ú<lambda>z!Handler.do_POST.<locals>.<lambda>«  s   ø€  $§(¢(¨3°Ñ"3Ô"3€ r   rÆ   éd   )Úmax_num_fieldsc                 ó>   •— ‰                      | dg¦  «        d         S )Nr
   r   rL  rM  s    €r   rN  z!Handler.do_POST.<locals>.<lambda>®  s   ø€  $§(¢(¨3°°Ñ"5Ô"5°aÔ"8€ r   râ   u4   <h1>SicherheitsprÃ¼fung fehlgeschlagen</h1><a href="r   u   ">Seite erneut Ã¶ffnen</a>i“  r1  r   c                 ó&   •— g | ]}|‰d z
  k    ¯|‘ŒS )i,  r8   )r9   Útrð   s     €r   ú
<listcomp>z#Handler.do_POST.<locals>.<listcomp>µ  s"   ø€ ÐRÐRÐR !ÀAÈÈcÉ	ÂMÀM˜AÀMÀMÀMr   é   u#   <h1>Bitte fÃ¼nf Minuten warten</h1>i­  zSELECT * FROM admin WHERE id=1rQ   rG   ÚhashuF   Anmeldung fehlgeschlagen. Admin-Passwort zunÃ¤chst per CLI einrichten.r¬   Trà   rá   rý   r'  Úq_r¾   rq   rr   zC<h1>Anfrage eingegangen.</h1><p>Deine Reservierungsnummer: <strong>u�   </strong></p><p>Der Bestand ist fÃ¼r dich zurÃ¼ckgelegt. Eine BestÃ¤tigung und die Abstimmung zur Abholung erfolgen persÃ¶nlich.</p><a href="u   ">ZurÃ¼ck zum Bestand</a>)r3  r;  r2  r7  r@  z<h1>Anmeldung erforderlich</h1>r2  r;  r   rƒ   r7  ÚconfirmÚ1u   LÃ¶schen bitte bestÃ¤tigen.r@  r#  r&  r$  iô  i?B u   Artikelangaben prÃ¼fen.Úimage_choicerG  r�   r�   r<   zJUPDATE products SET name=?,description=?,unit=?,stock=?,image=? WHERE id=?zJINSERT INTO products(name,description,unit,stock,image) VALUES (?,?,?,?,?)z<h1>Seite nicht gefunden</h1>r  u�   <h1>Speicherung derzeit nicht mÃ¶glich</h1><p>Die Anfrage konnte nicht bestÃ¤tigt werden. Bitte Bestand und Verwaltung prÃ¼fen, bevor du erneut anfragst.</p>i÷  u6   <h1>Bitte Eingabe prÃ¼fen</h1><p class="notice error">z</p><p><a href="u"   ">Bestand Ã¶ffnen</a> Â· <a href="u   ">Verwaltung Ã¶ffnen</a></p>i�  )/rÞ   rû   rb   ræ   rç   rî   rW   ÚrfileÚreadr×   r   rÊ   ÚhmacÚcompare_digestr  r   Úclient_addressré   ÚATTEMPTSrV   r,   r0   r‰   rR   rë   rZ   rí   rX   rì   r  rk   r   Ú
isinstancerê   rz   r�   rª   r“   r–   rj   Úmaxr¹   r+   ÚOperationalErrorÚUnicodeErrorÚIntegrityErrorr�   )r    r   ÚlengthÚctypeÚ	multipartÚlarge_okÚrawr¶   rç   ÚaddressÚfailuresr1   rã   rs   r©   rœ   ru   rq   Údescr&  r$  rµ   r:   r<   r‹   Úexcr   rð   s                             @@r   Údo_POSTzHandler.do_POST›  sµ	  øø€ Ø�Š‰ŒˆØ�zŠz‰|Œ|ˆðU	HÝ˜œ×)Ò)Ð*:¸CÑ@Ô@ÑAÔAˆFØ”L×$Ò$ ^°RÑ8Ô8ˆEØ-°Ð6ˆIØ ÐN T¨ZÒ%7ÐN¸D¼IÀgÔ<NˆHØ˜Šzˆz˜V°HÐ'G y yÀ%ÒHÐHÝ Ð!=Ñ>Ô>Ð>Ø”*—/’/ &Ñ)Ô)ˆCØˆFØð 9Ø˜:Ò%Ð%Ý$Ð%:Ñ;Ô;Ð;Ý.¨s°EÑ:Ô:‘��fØ3Ð3Ð3Ð3��å §
¢
¨7Ñ 3Ô 3ÀCÐHÑHÔH�Ø8Ð8Ð8Ð8�ÝÔ& s s¨6¡{¤{°D´I¸fÔ4EÑFÔFð Ø—’ÐxÕVWÐX[ÑV\ÔV\ÐxÐxÐxÐz}Ñ~Ô~Ð~Ø�Ø�xÒÑØÔ-¨aÔ0�Ý”i‘k”k�ØRÐRÐRÐR¥x§|¢|°G¸RÑ'@Ô'@ÐRÑRÔR�Ý�x‘=”= AÒ%Ð%Ø—N’NÐ#HÈ#ÑNÔNÐNØ�FÝ‘Y”Yð T "ØŸJšJÐ'GÑHÔH×QÒQÑSÔS�EðTð Tð Tñ Tô Tð Tð Tð Tð Tð Tð Tøøøð Tð Tð Tð Tàð o¥DÔ$7½ÀcÀcÈ*ÁoÄoÐW\Ð]cÔWdÑ8eÔ8eÐglÐmsÔgtÑ$uÔ$uð oØ(0°C°5Ñ(8•H˜WÑ%Ý$Ð%mÑnÔnÐnÝ—’˜W dÑ+Ô+Ð+Ý—’˜TœX tÑ,Ô,Ð,Ý"Ô0°Ñ4Ô4�”Ý%,Ô%:¸2Ñ%>Ô%>ÈÐZ]Ð`dÑZdÐeÐe�”	Ø%)¤Y•˜œÑ"Ø—’˜hÑ'Ô'Ð'Ð'Ð'Ø˜Ò#Ð#Ø�
Ø"&§*¢*¡,¤,ð ]ð ]‘J�C˜Ø—~’~ dÑ+Ô+ð ]Ý:DÀUÍDÑ:QÔ:QÐ.\¨e°A¬h¨hÐW\˜
 3 q r r¤7Ñ+øÝ˜c˜c &™kœk¨3¨3¨y©>¬>¸:ÑFÔF�Ø—’ð   YÐehð   Yð   Yõ  xyð  z}ñ  x~ô  x~ð   Yð   Yð   Yñ  Zô  Zð  Zð  Zð  ZØÐaÐaÑaØ”y Ô)ð Ø—N’NÐ#DÀcÑJÔJÐJØ�FØ˜9Ò$Ð$Ý—L’L ¤¨4Ñ0Ô0Ð0Ø—L’L‘N”N�N‘NØ˜YÒ&Ð&Ý!¥# c c¨$¡i¤i¡.¤.°#°#°h±-´-Ñ@Ô@Ð@Ñ@ØÐ.Ò.Ð.Ø�s˜9‘~”~¨Ò,Ð,Ý(Ð)FÑGÔGÐGÝ¥­s°3°3°t±9´9©~¬~Ñ >Ô >Ñ?Ô?Ð?Ñ?ØÐ2Ò2Ð2Ø�s˜9‘~”~¨Ò,Ð,Ý(Ð)FÑGÔGÐGÝ&¥s¨3¨3¨t©9¬9¡~¤~Ñ6Ô6Ð6Ñ6à'* s¨6¡{¤{×'8Ò'8Ñ':Ô':¸C¸CÀÑ<NÔ<N×<TÒ<TÑ<VÔ<VÐX[ÐX[Ð\bÑXcÔXc×XiÒXiÑXkÔXk ˜$�DÝ   G¡¤Ñ-Ô-�EØð D tð D°4ð D½3½sÀ4¹y¼yÍÈTÉÌÕSVÐW[ÑS\ÔS\Ñ;]Ô;]Ð`cÒ;cÐ;cÐklÐpuÐkÐkÒkÐkÐyÒkÐkÐkÐkÝ(Ð)BÑCÔCÐCØ ˜S Ñ0Ô0Ð:°F�FÝ ™œð 	S bØ˜3˜t™9œ9ð SØ"$§*¢*Ð-TÕWZÐ[^Ð[^Ð_cÑ[dÔ[dÑWeÔWeÐVgÑ"hÔ"h×"qÒ"qÑ"sÔ"s˜CØ#&ð LÝ&0Ð1JÑ&KÔ&KÐ KÝ)4°S¸´\À6È6Ñ)RÔ)R™J˜E 3ØŸJšJÐ'sÐvzÐ{ð  AEð  FKð  LQõ  RUð  VYð  VYð  Z^ñ  V_ô  V_ñ  R`ô  R`ð  vañ  bô  bð  bð  bå)4°T¸6À6Ñ)JÔ)J™J˜E 3ØŸJšJÐ'sÐvzÐ{ð  AEð  FKð  LQð  vRñ  Sô  Sð  Sð	Sð 	Sð 	Sñ 	Sô 	Sð 	Sð 	Sð 	Sð 	Sð 	Sð 	Søøøð 	Sð 	Sð 	Sð 	Sõ   u°¢| |  ¸Ñ>Ô>Ð>Ø—’˜hÑ'Ô'Ð'Ð'Ð'à—’Ð>ÀÑDÔDÐDÐDÐDøÝÔ'ð 	Að 	Að 	AØ�NŠNð  {ð  }@ñ  Aô  Að  Að  Að  Að  AÝ�L­'Ô*@ÐAð 	Hð 	Hð 	HØ�NŠNð  BÕTWÐX[ÑT\ÔT\ð  Bð  BÕnoÐpsÑntÔntð  Bð  Bõ  YZð  [cñ  Ydô  Ydð  Bð  Bð  Bð  DGñ  Hô  Hð  Hð  Hð  Hð  Hð  Hð  Hð  Høøøøð	Høøøs�   ¬E \8 Å.A7\8 Ç'\8 Ç5(H)È\8 È)H-È-\8 È0H-È1C7\8 Ì*B-\8 Ï(\8 ÐH \8 ØC['Û\8 Û'[+Û+\8 Û.[+Û//\8 Ü \8 Ü8%_Ý _Ý;A_ß_N)r`   )r#   r$   r%   rÛ   rÞ   r÷   rû   r  r  r  r  r  r/  r*  ro  r8   r   r   rÙ   rÙ   þ   sá   € € € € € ðð ð ð+ð +ð +ð$jð jð jð
ð ð ðð ð ð ðPð Pð Pðð ð ðð ð ð
1ð 
1ð 
1ðdð dð dð<, ð , ð , ð\XHð XHð XHð XHð XHr   rÙ   c                  óÞ  — t          j        t          ¬¦  «        } |                      dddgdd¬¦  «         |                      dt          d¬	¦  «         |                      ¦   «         }t          ¦   «          |j        dk    rœt          j        d
¦  «        }|t          j        d¦  «        k    r|  	                    d¦  «         	 t          |¦  «         n9# t          $ r,}|  	                    t          |¦  «        ¦  «         Y d }~nd }~ww xY wt          d¦  «         d S t          pd}t          d|j        › |› d�¦  «         t!          d|j        ft"          ¦  «                             ¦   «          d S )N)r#  ÚcommandÚservezadmin-passwordrù   )ÚchoicesÚnargsrF  z--porti�  )ÚtyperF  z)Neues Admin-Passwort (mind. 12 Zeichen): zWiederholen: u#   PasswÃ¶rter stimmen nicht Ã¼berein.z]Admin-Passwort gespeichert. Laufenden Server neu starten, um alle alten Sitzungen zu beenden.r   zWildfleisch: http://127.0.0.1:z (Strg+C beendet)z	127.0.0.1)ÚargparseÚArgumentParserÚ__doc__Úadd_argumentrb   Ú
parse_argsrC   rq  ÚgetpassÚerrorr\   rW   r›   Úprintr   Úportr   rÙ   Úserve_forever)Úparserr!   rQ   rn  Úprefixs        r   Úmainr‚  ö  sx  € ÝÔ$µÐ9Ñ9Ô9€FØ
×Ò˜	¨GÐ4DÐ+EÈSÐZaÐÑbÔbÐbØ
×Ò˜¥s°DÐÑ9Ô9Ð9Ø×ÒÑÔ€DÝ�L„L€LØ„|Ð'Ò'Ð'Ý”?Ð#NÑOÔOˆØ•w” Ñ7Ô7Ò7Ð7Ø�LŠLÐ>Ñ?Ô?Ð?ð	#Ý˜Ñ"Ô"Ð"Ð"øÝð 	#ð 	#ð 	#Ø�LŠL�˜S™œÑ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"øøøøð	#øøøåÐmÑnÔnÐnÐnÐnå�˜ˆÝÐS¨t¬yÐS¸&ÐSÐSÐSÑTÔTÐTÝ˜[¨$¬)Ð4µgÑ>Ô>×LÒLÑNÔNÐNÐNÐNs   ÃC Ã
DÃ"DÄDÚ__main__)9rx  rv  r{  rK   r]  r™   Úosr£   rX   r+   ré   Úhttpr   Úhttp.serverr   r   Úpathlibr   Úurllib.parser   Ú__file__r¦   r>   ÚROOTr-   Úenvironrç   Úrstripr   r   r³   r¥   r²   r¯   r  rZ   r`  Ú
Connectionr   r,   rC   rR   r\   rz   r�   r“   r–   r�   rŸ   rª   r¹   r»   r×   r  rÙ   r‚  r#   r8   r   r   ú<module>rŽ     sè  ðØ JÐ JØ €€€Ø €€€Ø €€€Ø €€€Ø €€€Ø 	€	€	€	Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø CÐ CÐ CÐ CÐ CÐ CÐ CÐ CØ Ð Ð Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !à€tˆH�~„~×ÒÑÔÔ&€Ø	ˆF�]Ð*Ñ*€à	„z‡~‚~�k 2Ñ&Ô&×-Ò-¨cÑ2Ô2€ð)ð )ð )ð �kÑ!€Ø
�‰-˜(Ñ
"€à&Ø(Ø"Ø$ð	ð €ð €	Ø"¨;¸{ÐT`ÐaÐa€Ø€Ø€ðð ð ð ð ˆwÔ!ñ ô ð ðð ð ðð ð ð`ð `ð `ðð ð ðð ð ð&Qð Qð Qð$
ð 
ð 
ð
Bð 
Bð 
Bð/ð /ð /ð	ð 	ð 	ðð ð ðð ð ð,ð ð ð& ð  ð  ðF 	[€ðuHð uHð uHð uHð uHÐ$ñ uHô uHð uHðpOð Oð Oð* ˆzÒÐØ€D�F„F€F€F€Fð Ðr   