diff --git a/app/resources.py b/app/resources.py deleted file mode 100644 index 80ad982..0000000 --- a/app/resources.py +++ /dev/null @@ -1,666 +0,0 @@ -# Resource object code (Python 3) -# Created by: object code -# Created by: The Resource Compiler for Qt version 6.8.2 -# WARNING! All changes made in this file will be lost! - -from PyQt6 import QtCore - -qt_resource_data = b"\ -\x00\x00'/\ -\x89\ -PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ -\x00\x00\x80\x00\x00\x00\x80\x08\x06\x00\x00\x00\xc3>a\xcb\ -\x00\x00\x00\x09pHYs\x00\x00\x07a\x00\x00\x07a\ -\x01\x95\xc3\xb8\xb6\x00\x00\x00\x19tEXtSof\ -tware\x00www.inksca\ -pe.org\x9b\xee<\x1a\x00\x00 \x00ID\ -ATx\x9c\xed]g\x80\xd5D\xd7~\x92\xdc\xbe\x9d\ -\xde;H_\xaa(\x08\xd2\xd1\x05\xa4(\x02J\x91\xde\ -\xde\x97\x22\x82\x9f HW@D\x94&\x0a\x226@\ -iJ\x07\xa5I/\xc2\x02Kg)\xc2\xc2\x02\x0b[\ -n\xbf7\xf3\xfd\xb8eSor\xb7\xdc\xe5e}~\ -%\x99\xc9d\x92\x9c9s\xe6\xb4\xa1\x08!P\x83\xdd\ -\xb8\x1eE\xd9\x98\x0e\x00Z\x00\xa46\x05\xaa\x1c\x01\xa2\ -\x01hU5\xf0/r\x0bN\x0axB@n\x00\xd4\ -\x19\x02\xecq\x1a\x9c\x9b_E\xa5457SJ\x04\ -\xb0\xdbq\xb3\x1a\xc5R\xe3\x01\xd2\x1d\x801\x07:\xfc\ -/r\x1fV\x02\xacf(vv\x0b}\xf9K\x81*\ -\xca\x12\xc0f$\x99\x8cV\xfb,P\xd4\x08\x00\x9a\xdc\ -\xe8\xe5\xbf\xc8u\xb8(\x0a_\x1a\xf5\xcc\xc4\x17Q\xca\ -*UA\x92\x00vYn\x97\xa0i\xf7F\x80j\x98\ -\xeb]\xfc\x17\xb9\x0f\x0a\xa7\x09qwjm\xa8pK\ -T$$\x80?-7\xeb\x11\x1a\x9b\x01\x14\x0fU\xff\ -\xfeEHp\x97b\xd1\xb1\xa5\xa9\xec)\xeeE\x9a{\ -\xb2\xd7z\xa7\xd4\xb3\xfc\xf3\xaf\xc5_\x8095=\xaf\ -\xbb\x11r$%\xdeB\xdfZ\xcdKL\xeb=\xe2\xd0\ -\xf6\xf4K\xcfq\xcb\xfc\x04p\x18\xff\x18\xdd\x94{\x1d\ -\x9e\xd1\x9f\x7f\xee\xf0\x09\x0c}!\x0e\xefw\xe8\x95\xd7\ -]\x099\xd6~\xbe\x0cw\xae\xde\xc0\xbe\xf5[\xf4\xf1\ -\xfb\x8eo\xdb\x8c$\x93\xaf\xccO\x00\x16\xab\xebc\x80\ -<\x9f7]\xcc}\xfc\xb1z#\x08!\xb8x\xe2\x0c\ -\xee^\xbf\x99\xd7\xdd\x09)\x12\x8edr\xfdkg\x13\ -\xca\x1bl\x8e\x09\xbes\x1a\xf0,\xf5\xbc\xd2\xfe3\x8b\ -\xebg/\xfa\x8fo]\xbc\x9a\x87=\x09=\xd2\x1e=\ -\xf6\x1f?I~\x04\x0a\x18\xb3\xcbr\xbb\x04\xe0%\x00\ -\x8a\xa5\xde\xc73\xbe\xd4{\x94t\xdf\x7flN\xcb_\ -r\x805\xc3\xec?\xb6dd\x00\x80\x89\xa6\xdd\x1f\x01\ -\x00\xbd\x0dW#\x01\xf2f\x1e\xf5-d\xb0\xa6g~\ -\x04\x97\xd3\x95\x87=\x09=X\xd6\xed?\xce\x5c\xf4Q\ -\xbd\x0e\xe2R\x04\xad\xb3i;\x22\x1fh\xf8\xec6\x9b\ -\xffX\xa3}\xa6\x99\x9d\x08n7\xeb?\xa6i\xcaw\ -h\xb2Y\xf5q4\x80\x16y\xd1\xa9P\xc3a\xb3\xfb\ -\x8f\x19M\xfe\x22\x00pu=\x14\xc59FK\x1a@\ -l\xc8;\x14b\xb8\x1cN\xb0\xeeL6\x98\xdf8\x00\ -W\xd9G\xd3\x99\xaa\x1f\x02*\x96\x06P.\xf4]\x0a\ --\xb8\xa3\x1f\x00h\x86\x09\xe9\xf3mf\x0b\xb6,\xff\ -\x096\xb3%\xa4\xcf\xf5\x81K\x00\x14\x87\x03P@y\ -\x1a@d\x1e\xf4)\xa4\xe0\xce\xff\x00\xa0\xd1\x86\xd6\x82\ -\xfd\xed\x94O1\xff?\x13\xb0z\xde\xd2\x90>\xd7\x07\ -\x227\x05\x00Q4\x00]\x88\xfb\x13r\xd8\xadB\x02\ -\x08\xdd\x14\xc0\xba\xdd\xd8\xf9\xc3:\x00\xc0\xee\x9f\xd6\x87\ -\xec\xb9\x5c\x10V\x9a\x03\x00\xd0\xd3\xa2\xda\xcf \x9c\x82\ -) \x94B\xe0\x9d\xab7\x90\xfe$\x15\x00p\xef\xe6\ -?H\x7f\xfc$d\xcf\xf6\x81'\x03\xf0\x09\x00\xf9\x82\ -\x00\x84S\x00\x13B\x0e\x90\xfa(\x85w~\xfb\xf2\xf5\ -\x90=\xdb\x07\xc2f.\x03\x91\x1f\x09\xc0iw\xf0\xce\ -C)\x038\x1dN\xdey\xea\xc3\x14\x99\x9a\xb9\x07\xb9\ -U\x00\x90O\x08\xc0\xe5\xe4\xff\x04\xad.t\x04\xc0\x08\ -V\x1c\xa9\x1c\xbd|(\xc0\x1b\xfd\x10\xc9\x00\xf9\x83\x00\ -\xdc.7\xef\x5c\xab\x0b\x9d\xdcKk\xf8\x04`\x09\xb1\ -\x1dB\xe8\xf0C\xe5O\x0e\xc0\xd7\xfd\xeb\x8c\x86\x90=\ -[\xc8\x01X\xc1\x88\xccm\xb0\xac\x90\x00\xf2#\x07\x10\ -L\x01:}\x089\x00\xc3\xff\xc4\x5c\x8ddH \xe4\ -\x00\xf9r\x0a\x10|t\xadA\x1f\xb2g\x0b\xb5\x8e\xac\ -;\xb4\x1c@4\x05\xe4K\x02p\x09\xa6\x00}\xe8\x08\ -\x80a\xf8KN\xb5\x8189\x05\xe1\x94\x93/\x09@\ -$\x03\xe4\xe1\x14\xc0hBk\x87\x10M\x01y!\x04\ -\xb2n\xb7h\x14\x86\x12J\xc1\xfe\xf5\xdb\x90\x94x\x0bQ\x85\ -b\xd0\xacK\x1c\x8a\x97/\x03\x80\xaf\x08\xd2\x061\xff\ -\x1f\xde\xb2\x1b\xd3{\x8d\xf0\xff\xf8\x02E\x0bc\xe4\x17\ -3\xf0\xd2k\xed$\xeb\x13B0>\xeem\x5c8~\ -\x1aQ\x85\x0a\xa0J\xbdZ(Q\xa1,\xaf\xce_\xbf\ -\xed\xc0\x9e\xb5\xbf\xe1\xd2\xa9\xb3`\xddnP4\x8d\x0e\ -\x03zb\xd4\x173E\xed\xa5\xdcKFxt\x94$\ -\xd7\xbas\xed\x06VL\x9e\x8b#\xdb\xfe\x00\xcb\xb2\x18\ -\xbbd6Z\xf7\xec\x22\xaa\x97cB\xe0\xeayKy\ -?\x1f\xf0p\x83\x11M;\xe1Z\xfc\x05\xd9\xfbn]\ -\xcat\xc1\xe6z\xe6\x12\x96\xc5\xeayK\xd0\xb9D,\ -\xda\x17\xa8\x8a\x91\xcd\xbb\xe2F\xc2e\xb5\xdd\xe1a\xdf\ -\xfa-\xe8[\xa39\x16\x8c\x9c\x88\xb5\xf3\xbf\xc2\xd7\x13\ -?\xc1\x80zm\xb0o\xfd\x16\x00|=\x80\xda) \ -)\xf1\x16f\xf6\x1d\xc9\x1b\xf5)\xf7\x1f`j\x8f\xa1\ -\xf8y\xeeb\xc9{\xce\x1f9\x89\x0b\xc7O\x03\xf0\xe8\ -\xfc\x8f\xef\xdc\x87MKW\xf1\xea\xc4\x1f8\x8a\x0b\xc7\ -O\xfb\xe5\x12\xc2\xb2\xf8\xfd\xeb\x1fE\xae\xea\xd7\xcf^\ -D\xcf\xca\x8d1\xff?\x13 \xc4\xf1\x9d\xfb0\xa4Q\ -\x1c\xf6\xad\xdf\x02\xbb\xd5\x06\xa7\xdd\x81/FO\x92\x8c\ -z\x22\xc8\x01!\xf0\xc1?I\xf8\xe1\xe3/$\xcbR\ -\xee%cb\x97~xp'I\xb2\xfc\xce\xb5\x1b\xfe\ -c\x9b\xc5\x13\xa0\xear\xba0\xf9\xcd\xc1\xf8\xe6\xc3\xd9\ -\xfeN'\x1c=\x851\xad\xdfDR\xa2(~1 \ -\xfe\xda\xb4\x1d3z\xff\x17\x19\xa9\xfcpx\x87\xcd\x8e\ -9\x83\xde\xc3\xc3\xbb\xf7xz\x00\x9dA\x1d\xa7Y2\ -~\xba\xa4\x07\x0f!\x04\xcb'\xcf\xc1\xd6oW\x8b\xca\ -\xce\x1d:\x1eT\xdf\xb98\x7f\xe4$\xef\xfc\xcf5\x9b\ -\xe0v\xb9\xb0\xf7\xd7\xdf\x91\xf1$\xf3\xdd.\x9e8\x83\ -\x8f\xba\x0f\x16\xf5\xcd\x92\x96\x81\xc3[w\x8b\x1b\xce\x09\ -!p\xf5\xbc%\x01\xe7\xbf\x87w\xefa\xfe\x88\x0f$\ -\xcb\x1e\xdf{\xe0?\xd6\x1b\x0d \x84`\xde\xb0\xf7q\ -x\x8b\xb8\xb3\xe9\x8f\x9f`\xc1\xc8\x89j\xba\x04\xc0C\ -\x98s\x06\x8d\x15\x19<|\xb0[\xacX9\xed\xb3\xa0\ -e\x80+\xa7\xcfI\xf6\x8f\x8b/\xc7L\xc6\xbd\x1b\xb7\ -y\xd7\xb8\xef\x1a,\x1e\xde\xbd\xc7;OL\xf0\x84\xf5\ -;\xed\x0e\xdc\xb8\xe0\xe1\x8c\x96\xb4\x0cL\xed9T\xf6\ -_\x5c\xf9\xfb\x9c\xe8Z\xb6\xa7\x00K\xba\xd9\xef\xd1\x12\ -\x08\xc7v\xecE\xfc\x81\xa3\xa2\xeb6kfX\xba1\ -<\x0c\xdbV\xae\xc1\xae\x1f\xe5\xdb;\xb1\xfb\x00\xce\x1d\ ->\xa1\xf8<\x00X6a\x16,\x1c\x7f\x7f)\xec\xfc\ -a\x1d\xae\x9e>\xef?W#\x03lZ\xbaJq\xc5\ -\xe2\xb4;\xf0\xdd\x8c\xcfy\xd7\xac\x16\xc9\x10|U\x10\ -\xfeTKZ\x86\xff\xf8\xce\xd5\x1b\x00\x80\x15S\xe6\xe2\ -\xc1?\xd2\x9c\x16\x00n_\xbe&\xbe(x\x8d\xa0m\ -\x01\xfb\xd7o\xe1E\x96\x04\xc2\x9e_\x7f\xe7\x9d\xbb]\ -.\xb88\xf6psj\x1a\xbe\xfa@,\xec\x08\xb1e\ -\xf9\xcf\x8au\xee\xdf\xba\x83}\xeb\xb7*\xd6c\xddn\ -\xec\xf9%\xb3_J2\x80\xcdl\xc1\xbeu[\x14\xdb\ -\x05\x80\x83\xbf\xef\xe0\xbd\x9f1\xcc\x14\xa0v`\x84E\ -E\xf0\xce\xed\x1cbz\x9c\xfc\x00\xc9\xb7\xefb\xf3\xf2\ -\x9f\x02\xb6q\xeb\x92\x98\x00\xb2\xcd\x01\x0em\xde\xa5T\ -\xc5\x8f\xb3\x7f\x1d\xe3\x9d\x0b\x07\xd1\xee\x9f7\xaa\x0a\xcf\ ->\xb6c\x8f,[\xf7a\xd3\xd2U\xaa\x0d+\xdc\xd1\ -\xacD\x00\xa7\xfe<\xa8\x9a\xe0-i\x19\xb8\x1a\x9f\xe0\ -?/Z\xa6\xa4\xaa\xfb\xa4P\xb4L)\xde\xb9\xdb\x9d\ -9m9\xacv\xac\xf9l)\x8f\xd8\xa4\xf0PB\x0e\ -\xcb\x969\xd8a\xb3\xf3\x96qJx\x94\x94\xcc;\xd7\ -h5<\xcd\x97Zm`\xea\xc3\x14\x5c9s^\xb6\ -\xdcn\xb5a\x9b\x84\x10\xa6\x06J2\xc0\x91\xed\x7f\x06\ -\xd5\x1eweS\xbfU\xd3,)zh\x86Al\xd3\ -F\xbck\xdch\x9e;\xd7n`\xdb\xca5\x8a\xed\xb8\ -\x9c.\x91\xda;[\x0e!\xa7\xf7\x1d\x16I\x9b#?\ -\x9f\x8e\x9d\x19\xd7\xb0\xfc\xd4.\xb4\xec\xdeI\xd0\x011\ -\x85fU\xf3vb\xd7~\xd9\xb2\xf8\x03G\xfd\x8e\x96\ -\x5ch\xb4\x1a\x94\xab\xf1\x1c\x22\x0b\xc4\xc8\xde\x1bH\x17\ -O\x08\xc1\xb1\xed{x\xd7j7m\x84\xdf\x92\xcfc\ -\xc3\xdd\xd3\x18\xb5`\x06\x8c\xe1a\xbcr\x97#S\x09\ -S\xb6Ze\x0c\x9a\xf9\x7f\x88*X@\xf6\x19>\x84\ -EE\xa0X\xd9R\xd0\x1b\x0d\xe86j\x10\x0a\x14+\ -\xc2+\xe7r\xb7\xbd\xbfn\x96\x14\xfc*\xd4\xaa*Z\ -\xfb;\x04\x1e\xd0B\x0e t\x09\x0b\xa8\x08:\xb6\x83\ -\xff1\xea6o\x8c\xd7\x86\xf4\x06\xe0y\xd9\x09+\x17\ -\x80\xa6i\xec\xfey\x03\x00 \xaa\x90\xf8\xc5\xb5:]\ -\xc0\x80\x08\x1f\x97\x10\xbe\xe0\xf9\x00\x82\xe0\xb1\x9d{y\ -\xe7\x14E\xa1\xeb\x88~\xe8?u\x1c\xf4&#\x9cv\ -\x07\x96M\xfc\x18\x1b\x16}+\xf1J\xf2\xed\xbb\x92K\xbc\xa4\xc4\ -[\xfee\x11\x00\x14+W\x1a\x83f\x8au\x10\x14E\ -\xa1\xcf\x87cD\xd7\xe9\x00\x1f>\xe1(/\x7f\x12Z\ -\xf5\xe8,Y\xaf\xe7\xb8\x11`4\x1a4l\xd3\x0c\x11\ -\xd1Q\xb2\xed\xf9\xfa\xc1\x95\x83\xd4\x0a\xaer\xaec\xad\ -{vA\x87\x81o\xf9\xcf\x85\x84$l_i\x0a\x90\ -%\x80\x84\xa3\xa7x7\xbf\xfcz{YSf\xff\xa9\ -\xe30u\xed24\xed\xfc\xaa\xa8Lj\xdd]\xada\ -\x1d\xbc\xfe\x9f\xfe\xbckEJ\x97\xe0\x11\x18!\x04\xb7\ -/\x8b3y\x5c\x15\x08\x87\x9d\x86\xf6\x81F\xc6\xcb\xb7\ -Z\xc3:\xa8\xd9\x98\x9f\xe9.\x10\x07\xe0\x12@Dt\ -\x14\x1a\xb4\x11s\x10\x00\xa8X\xbb\x1afo\xfe\x1ec\ -\x97\xcc\x96m\x8b\x0b\xee(u\xab\xf4\x09\x94Z\x05\x19\ -\xc3\xc30l\xce$\xde5\xd1\xfb\x08X\xbc\x90 T\ -\xaf\x02\x84\xa3\xa1^\x8b&\xb2\x9d\xd5\x1b\x0dh\xd2\xb1\ -\xadH\xc2\x04\xa4\xa5\xee\xe1\xf3\xa6HJ\xcbB\x0e\x93\ -|\xfb\xae\xa8N\xe2\xb9\xcc\xc4\x974\xc3\xa0]\xef7\ -d\xfb\x05\x00\xcd\xba\xf0\x89RN\x06\xb8{\xfd&\x9e\ -Q\x09\xbd\ -t}\x10\x12|l\xb3\x17\x02\xb6\x1b\x0c\x18\x0e\x07P\ -\xed\x13(\xa1\x88l?\xe0-\xd15a\x94\x93\xf0{\ -\x0b\x9f\xc70*8\x00!\x04WNg\xea\x95+\xc5\ -\xd6\x10i\xaa\xd4B8\x8a\xba\x8f\x19\x22[\xb7\xccs\ -\x15y\xe7\x0f\xef\xde\x17\xd5\xb9\x91\x90I\x00u[4\ -\x16\x95\x0bQ\xa1&\x7fY('|\x09\xf5\xe8B\xc2\ -\xc9\x0e\xb8~\x81Y\xf5\x0a\xae\x14[C$\x90\x02b\ -\xf76\xa1L\x22t\x88\x15\xca@\x92\x04\xf0(\xe9>\ -O\x17]\xb3q\x83\xe0z\xcb\x01\xf7\x83\x17-S\x12\ -\xf5[7\x95\xad[\xb8d1\xde|\xceU\xb2\x00\x9e\ -y\x91k-\xac\x14[C\xf1\xf9\x14M\xa3X\xb9\xd2\ -\x9c\xfeHs\x00\xae\xd9\xda\x14\x19\x8e\x0a5\x9f\x93\xac\ -\x97\x15dE\x19&D\xe3\x0em$\xaf\x1b\xc32\xf5\ -\x12\x860\x93\x7f%\xe4C\x968\x80\xd06]\xb9\xae\ -xy\xa7\x16\xdc\x0fn\x083I\xca\x09>P4\x8d\ -\x98\xc2\x85\xfc\xe7B\x13oZ\xca\x13\x9e\xa6KjD\ -H\x81+P\xc9\xc9\x00\xdcw\xae\x14[#G]\xb7\ -\xb8\xdf \xabn\xe1\xf5ZJ\xcb`\x05\x8a\x15\xf1\x7f\ -\xd3\x8a\xb5\xaa\x89\xca\xb9\x09\xa2\x00\x952\x80\x90\x00\xaa\ -\x08\xe6\xe6`\xc0\xe5\x00j\xd8_L\x91L\x02\x10\x86\ -Q\xa5\xdc\xcbT5S\x14\x85\x92\x15\xcb\xa9\xea\x03W\ -\xa0\x92\xe2\x00\xd6\x0c3O\xe0\xcc\xce\xfbJ!+\xcb\ -@.\xf4&#\xaa6\xac+Y\x16\x16\x15\x81\x0a\xde\ -\x1f/\xa5\xf7P\x12\x02%'\xc4\x9b\x1cvh\x083\ -\xa9\x1eiR\xe0\x13\x802\xf5\x87Eg&,1s\ -\xa6!\xc0\xe3\x91\xe3CxT$\x0c*\xado\x84p\ -\x09@\xfc\xca\xb7\xaf\x5c\xe7-y\xab\xd4\xcbY\x02\xe0\ -\x12\x9d0NQ\x0d*\xd5\xae\x1epE2z\xe1,\ -\xec\xfc\xe1Wt\xfd\xcf\x00Q\x99[\xf0\xcd\x85\x8a#\ -\xc9V\x939N\x8de\xaaT\xcc\x96+3\x8f\xfaU\ -\xac\x81\xb9B\x8d%]\x9e\x00\x22\x0b\x05\x96\xfe\xb9\xe0\ -z\xc6\x0a\x835\x01\xfe\xfb\x02\x1e5wN\x82\xb7\x0c\ -\xcc\x02\x07\xa8R\xbfv\xc0\xf2j\x0d\xeb\xc8\xae\xac\x84\ -\x1c@\xb8\x0a\x92\x11\x023Ym\xa9\xca\xe5UuR\ -\x0e\xc1N\x01Z\x8e\xde@hCHO\xc9\xf4\xa0U\ -cp\xf1C\xc1\xb9\x83\xfb\xbe\xc1L-j\xc1\x1du\ -\xc29Y\x0d\x8a\x95-\xa5\x5cI\x06B\x8eC\xd3*\ -\x08\x80;\xd2JU\xce:\xfb\x07\x82_\x03s9\x80\ -\xb0\xf3N\x8e\xe5-\xa2@\xb4\xea>p\xd9\xbb\x14\x11\ -re\x8bB%\x8b\xa9\x9eZ\xd4\x22\xd8i0'!\ -\x96\x01\x14V\x01\xac\xdb\xcd\xd3\x88\x15/_ZX%\ -(\x04\xcb\xfe\xb8\x8a\x0c\x97\x8bo^\xe6\xfa\xbf\x07\x13\ -\xe3\xcf'\x00\xf1\x0fx\xc4!\x80\xe2\xe5\xb2\xf7\xbeR\ -\xc8\xee20;\x015Ak\x02\x9f\xb8\x1fP\xaa\x0f\x8f\x93\x1f\xfa\x8f\xb3\ -\xfb\xbeR`\x98\xec/\x03\xb3\x0a\x91\x1e@\xa3@\x00\ -\xc2y7\xbb\x1f\x84\x0e\x92\xfdqe\x00a\x5c?\x8f\ -\x00\x82\x09\xf0\xe4\x10\x80\x14\x17\xe2\xbes\xa1\x12\xc5\xd4\ -\xb7\xab\x12\xd9]\x06f\x07\x22M\xa0\x12\x07\x10\x86\x19\ -I9y\x04\x03\xbe\x12D\xf9\xe5\xb9j\x22!\xe7s\ -pd\x80\xac\xa6z\x93\x22B\xae3JdA\xf5\xab\ -\x0b\xb5\xe0/\x03\xf3v\x0aP\x5c\x05\x08S\xaae7\ -d\x8b\xfb@\xb7\x0a\x09\xd8\xca\x19\x8dB\xc3\x06\xc3\xd1\ -\xce\x05\x95\xf2\x9d\xa3}\x94\x9a\x02\xb8\x04\x90\xdd\xf7\x15\ -\x82\xb9\x92\xc8\x97\x01B<\x05\x88m\x01\x0a\x04 t\ -\xcd\xcan4m\xb0\xf3\x1f\xd7#W(\xe8q3{\ -\x08=_\x02\x81\xeb\x04!5\x058\xec\x99\xef\xac6\ -rH-\x0c3\xe6\x0b\xbeA\xf0S\x80\x1c\x07\xa0R\ -\x943\x8e\x09\x09^\xd9!D!\x94(XpY\xb5\ -\x1a!\xd0\xc2!\x00!\xf1q\xcf\xadfu\xae\xdb\x00\ -\xdf\x09B\x8a\x08\xb9\xfd\xa2\xe9\xec\xbd\xaf\x10\xcc\x99\xf3\ -\xd0p~TV4\x81r0|\xb2P\xb1N\xd0\xab\ -\x00\xe1GW\x13\x12\x1d\x08\x5c\x96\xa3f\x19hUI\ -\x00\x0f$|\x05d\xfb@\x07\x9e\x02\xb8l_\x98W\ -8\xbb\xa0\xac6ho\xfe\xe3?\xcf\x92\x10(\xc1\x01\ -t?o\x80\xe6\xd4Y\xc5[\x95T\xc1\x12\x04\xc0g\ -\x81B\x99 X\x04\xab\x04\xc9\xe0\xb8{G\xc4\xf0\x95\ -=\x06c\xa6\xa93\xf96_}\x1b\x08\x14\xc5\xe5\x00\ -\xe2\x1f\xc0}\xe7\xec\xbe\xaf\x08V\x1b4\x1c\xb9&+\ -\x9a@!\xa8\xc7O`|\x7f\x06\xd8\x02\x81\xfd\x11\x01\ -\xb1\xd0)\xccY$\x22\x00\xa1\x10\xf4$\xf9\x91\xb0J\ -P\x08f\x15@\x08ARbf\xc0eL\xd1B\xbc\ -\xf2\x02\xc53}\xe7-i\x19\xa2\x80J9p\xa71\ -)\x9f<\xee;g\xf7}\x85\xa0m6p\x99nN\ -L\x01\xc6\x09\x1f\x83~\xf0\x08\x88Q\xd6\x86\x06\xed\x0f\ - t(\xb8\x7fK\xfdH\x93\x82\x92\x8f\x1a\x17\x8f\x92\ -\xee\xf3\xa6\x80\x02E\x0b\xf3\xca\x0b\x97\xe4'\xa2\xb8x\ -\xe2\x8c\xaa>\xf0v\xc9P \x80\xec\xbe\xaf\x08V;\ -\xef#gW\x08\xd4\x1c<\x06\xfdwk=\xd7U\x11\ -@\x902@t\xa1\x02<\xd3\xe3]N|\x7fN@\ -\x98\xb3\x86\x8bK'\xf9igb\x04\x04P\xa8$_\ -Is\xfe\x90r\x141!\x84\x97\xb1[J\xa6)\xc8\ -Q\xfe\xdc\xbd~C\xb1M\xd5p\xba\x00\x97\x8bgr\ -\xcd\x8e\x22\x88r8a\xfa\xefD\xbfL\xc0\xc6(O\ -\x01A\x13\x00\xcd0(\xc4\x19iBg\xc9\xec\x22\xd0\ -\x07\x10\x06\x97\x0a\xf5\xf2\x05\x8b\x15\xe1\xc9\x14\x07\x7f\xdf\ -\xa9\xf8\xbc\xb3\x07\x8f\xf3F\xb5T\x94R\xd1\xd2%\xfc\ -\xc7\x89\xe7/+\x86\x9c\xab\x05\xe5\x15(\xb9\x9f\x9c\xcd\ -\x08~\xdb\x18\x1f\x07\xd0\x7f\xba\x18\xcc\x85+\x99\xd7\x15\ -b\x12\x80,\xa8\x82\x01\x8f\x8f\xbe\x0fg\x0f\x1eW\xa5\ -\x89\xba}\xf9z\xe0dE\xfe\x0eI\x13\x00aY\xec\ -\xdf\xc0\x0f\xf7.W\x83\xef\x97G3\x0c\xcf9\xe5\xee\ -\xf5\x9b\x8a\xc9\xaaV\x7f\xcaO\xe7b\x95 \x80\x22\x9c\ -\xa8^\xd6\xed\x0e\x18\x96\xe6\x83%-C\x94 B\x04\ -on\x04\xee\xd7#\x8f\xc51\x8dj\xc0\x5cM\x84Q\ -\x90\x9a\x86\xa8\xb0\x88\x06\xad\x0a\x06\xf8\xf6\xe7\x07w\x92\ -pf\xff\x91\x80\x0f\xb9\x16\x7f\x01\xc3\x1aw\xc0\x8a\x8f\ -\xe6*wHF\x08:\xb6c/\xcf-\x8b\xa2i\x94\ -\x93p\xcc\x10z\xeb\xac\xfbr\x85\xec\xb3.\x1c?\x8d\ -c;\xf6\xf2\xaeIq\x00\xa1\xbd]\x98\x0bI\x08\xd6\ -\xed\xc6\xe47\x07aT\xcb7\x02*\xa4h/\x07\xe0\ -\x8eA\xd6\xe1\x80F\xe1{J\xc18j\x12 \x98\xbe\ -\xd8,\xc8\x00\xaa8\x800\xc6\xef\xf7e?\xc8>\xc0\ -\x92n\xc6\xf4^\xc3a3[\xb0u\xe5jE]\xf7\ -\xacwF\x8aR\xa3\xd9\xcc\x16,y\x7f:\xefZ\xf1\ -r\xa5%\xed\xf2\xcf\xd5\xe7\xefr\xb7\xf7\xd7\xcd\xb8\xc9\ -a\x8b>\x10B\xf0\xf5\xc4\x8fE\xd7\xa5\x08\xa0b\xad\ -\xea\xbc\x91q`\xe36\x9e\x85P\x88\xef\xa6\xcf\xc7\xe9\ -}\x87\xf1(\xe9>\x0eo\xfdC\xb6\x1e\xbc\x04\xc0\xfd\ -\x05,\x00\xa3L\xbe%90\xa7\xceA\xfb\xe7_\xe2\ -\x82\x18\xe5\xfd\xbe\x84^X\xaa8@\xf5\x17\xea\xf1\xce\ -\xf7o\xd8*\x9b\x00i\xfe\x88\xff\xc3?W\x12\x01\x00\ -\xe6\xd4t\xdcH\x10\xff\x0c.\x8en\xdf\x83wj\xb5\ -\xc4w\xd3\xe7\xe3\xd4\x9f\x7fa\xdf\xfa-\x18\xdd\xaa\x9b\ -\xbf\x0d\x1fj5i(y\x7f\xd5\x86|\x02p\xbb\x5c\ -\x98\xf5\xce(\xd1H\xdc\xb2\xfcg\xc9\x945RS\x80\ -)2\x1c\xe5\xaagr\x1b\xbb\xd5\x86\x15\x93\xa4\xc3\xbe\ -N\xec\xda\x8f\x9f8\xac8`:\x1b\xafN\x81;\x05\ -\xb0\x004{\x0fA\x13DB)\x8d \x18\xd6\xdf\x96\ -\x0a\x0e \xd2\x03\x088\x80\xa4I\xadb\xed\x1a\xd0\x1b\ -\x0d~\xad\x18!\x04\xd3\xde\x1e\x81\xf9\xbb\xd7\xfa\xdd\xa5\ -\x08!\xf8v\xca\xa7\xbc\xf4+\x80\xc7\xbb\xa6bm\xb1\ -{2\x17\xa9\x8fR\xf0\xfd\xac\x05\x01\xeb\xd4o%\x1d\ -?P\xa5n-\x14(Z\x98\xe7\xb5t->\x01\xff\ -m\xde\x05\xbd'\x8cBL\xd1\xc28\xb0a\x1b6,\ -^)y\xbf\x5c\xa8z\xf5F\xf5x;\x8co[\xf5\ -\x0b*\x95-\x85N\x9c\xe8\xde\x8b'\xce`\xd6;\xa3\ -xK\xc9@\x89\xa1(\x09\x0e\xe0\x83a\xf6Bdl\ -\xfaN\xf6^^;2}V#\x03\x08\x85@U^\ -\xc1\x1a\xad\x065^l\x80S\x1c\xb6\x93r/\x19C\ -\x1a\xc5\xe1\xd5w\xba\xa3L\x95\x8a8\xb6s\xafd&\ -\xad\x9c\xf0\xa7\xa7(\x0a\xf5Z\xbe$]F\xd3h\xd2\ -\xa9\x9dhZ\xba~\xf6\x22\xa6\xf6\x1c\xa6\xd8\xb6UF\ -\x0a\x8fm\xf6\x226\x7f\xc3\xcf\xc1\xf3\xe5\xf4\xf98\xba\ -n\x0b\xea\xf7\xeb\x81\xb4G\x8f\xb1\xee\xcb\xe5b\x02\x0a\ -d+\x91\x90\x01|n,\xda\x9d\xfb\xa09y\x06\xae\ -\xfaY\xdb\xb8\x95\xd04HD\xb8b=\xb19\x98\xff\ -\xcbe\x8d\xea-\xbbw\xe2\x11\x00\xe0\x19=RI\x17\ -\xb8\xe0.\xa9\xb2\x8a\x9a\x8d\x1b\x22\xbapA\xd9\xf2f\ -]\xe2\x02\xca%\x81`\xb3H\x13\xc0\x8bq\xad`\x8a\ -\x08\x13-\x01\x8f%\x5c\xc6\xb1q\xd3d\xdb\x0b\x94\x17\ -\x88\xb6\x889\x00\xf7\x83\x1b>Y\x88\x8c_\xbe\x96\xbe\ -\x99\xeb\xc5$U\x1e\x15\x09\xa8\xf0\xd6\x16\xae\x02TE\ -\x06\x01@\xb3\xce\xaf\x06m\x1b/V\xb6\x14Je#\ -\x86\xc0\x87\x8e\x83{\x05,\x8fm\xdaH\x94\x82U-\ -\x1c6\xbb\xe4R\xd4\x10fB\x93\xd7^\x09\xba\xbd\x86\ -m\x9a\xc9\x17J\xc8\x00\x5cG6\xed\x96\xdd\xd0p\x92\ -LqAedH^\xf7\x81\xa8P\x02\x01Rz\x00\ -/\x09\x12\x02\xdd\xba\xcd\xf2\x04`\x8a\x0cG\xb3.q\ -\xaa\x1e\xe2\xc3+}\xdf\xcc\xb6\xf98\xa6H!4\x93\ -\xc83\xc0\x05\xcd0\xe8\xf1\x9e2\xbb\xf7A\x98\x7fG\ -\xce\x99\xe4\xd5\xbeo\xaan\x13\x00JT(\x8b\xda\x82\ -\xe4N\xf8\xf6\xf3l\ -\xfb\xd3Wm\x10\x8b\xce\xc3\xdeQUW\xa3\xd3b\xfc\ -\xd7\xf3\x14\xa3\x96\x06L\x1d\x87ZM\x9e\xf7s\x81r\ -\xd5\xaa\x04\xac?p\xfaxU\x5c\xac\x03\x80\xb8\x1f\xd6\ -\x81\xbe\x97,_\xc9;\x05pG}\x11a\x1dB`\ -\xe0,+u\xdf\xff\x0a\xcd\xdeC\xe0\x92\xa8Qx\x0f\ -\xd4\x19\x82\x00 \x9c\xa3..\x92\x9e\x01\xad \xed\x9f\ -\xa2\xc8>p\xfa\xff\xa1|\xcd\xaa\x01\xeb\x0c\x9f;Y\ -2\x7f\x90\x14Z\xf5\xe8,\xf9\xd3\xcaT\xad\x84)k\ -\xbe\x0ajc\xe7\xba\xcd\x1b\xa3\xdfGce\xcb;\x0f\ -\x7f\x07]\xbd\xa9h\x9av\xf6\xcc\xef-\xbb\xbf\x16\xb0\ -\xcd*\xf5j\xa3\xef$qn!.b\x01L\x00\xa0\ -\xdd\xfa\x07\x22\x1a\xbe\x02\xdd\xc6m\x92\xf5|\xcb@\xee\ -\xa8\x97\xe2Y\xbau[@_\xbe\x0e*\xe51\x8c^\ -\xe5\x157\x19\x9dTf\x065K@\xfa\x9f$\xd4\xde\ -\x9d\x99\xf8J\x18\xf1\xe8x\xa3\x03\x98>\x1f\x8e\x9e\x12\ -\xa8\x11\xad^\x87F\xaf\xb4\xc0\x81\x8d\xdbx9\x03\x00\ -\xcf\x5c<\xe2\xd3\x8f\xd0yX_\xd9\xfb\xe3\x0f\x1c\xe5\ -\xa9\x92\x97\x1c\xda\x8c\x16\xdd:\x82\xd60`4\x1a\x14\ -/W\x0aq\xfd{b\xdc\xd29Y\xf2\xc8\xad\xd5\xa4\ -!\x0a\x16/\x82\xf3\x87N\xf8-}\xc6\xf00\x0c\x9e\ -\xf9\x01\xfaL\x1c\xe5\x1f\xcdU\x1b\xc6\xa2H\xa9\x12x\ -mpo\x91W\x8c\xa8\xcd\x97\x9e\xc7\x83\xdbwq\xf5\ -\x8cX@\xab\x0f`\x012G%e\xb1B\xb7n\x0b\ -4\x17\xae\xc0\xd9\xfcE\x80cN\xd7\xee\xda\x07\xcd\xa1\ -\xe30\x03\xd8\xeb\xbd6\x08\x80h\x9dD\x08\xe8\x8c\x0c\ -hv\xed\x87\xd6k|;\x03\xc0\x97'm\x18\x00\xa1\ -o\xb6\xb3u3\xb8\x9aK'\xc8\xa0R\x1e\xc38\xf3\ -\x0b\x84\xf7\x1b\x85\x22\xe7/\xe1\x18\x80G\x00>\x00\xe0\ -\xb3\xaf\xb2\x85\x0a\xc0\xbc~\x05\xa8\xdd\xd6\x1b\xaa|\x8e\ -S\x1f\xa6`\xe5\xb4y\xd8\xb3\xf6wd\xa4\xa6\xa1b\ -\xed\xea\x186g\x92\xe2\xc8\xff~\xd6\x02|7}\xbe\ -\xff|{\xda\xd5\x5c\xd9\xbe\xdda\xb3\xe3\xf2\xa9x\xd8\ -,6TkX'\xcb\x19M| \x84`\xc7\xaa_\ -\xf0\xcb\x82\xafq\xf3\xc2\x15D\x00x\x1b@\x7f\xf0\xad\ -{\xbc{\x8a\x16\x86y\xd1\xc7p\xb6o\x0d\x000\x8d\ -\x9b\x06\xfd\xc2\x15p\x00\xe8\x03\x0f\xbb\xfd\x012l\x97\ -a\x00\x96\xf5\xcf\xfdG\x00\x8c\x80\x87\xdb,\x878\xbd\ -\x9bu\xf6\x87\xb0\x09e\xaet3\x8c\x0b\xbe\x86\xe1\x8b\ -\xaf\x01\x8e\x10\xe9\x00`\x01\xc0\xe5\x19\x19k\xbe\x82\xf3\ -\xb5v\xea\x09\x80\x0b\xbb\xc5*r\x1c\x91C\xa8\x08 \ -7\xe1\xdes\x10\x05\xe2\xdeV\xbd\xbb\x86\xb3k{\x98\ -\x17\xce\x84q\xd2\x1c\xe8\xbd\x09\x9e\xdd\xf0\x08\x83\xc1\xec\ -Z|\x0d\x9e)CJ\xb22/\xfb\x14\x0eo\x82,\ -\xca\xe1\x84\xee\xfb_`\x9c\xf6\x19\xa8\x006\x0c\x1f\x1c\ -=\xbb\xc0\xbc\xc2\xf3O\xb2\xf4'\xd4\xfe|@*O\ -]\xcez\xdd\x86\x02L\x8b&p\xb7k\x0eZ`Y\ -\x94\x83v\xfd\x16D\x1e9\x09\x96\x13T\xc3@\x9es\ -\xc8\xa1b\xa0\xc2\xe8(\xc0\xed\x86\xee\xc7\xf50\xce\x98\ -\x0fZ\x22\xa3\x9a\x14\xd8bE`\x99\xf7\x91\xff<_\ -\xec\x1b\x98\x13\xb0M\x1b\x0f\x12\x84\x9a\x9b\xbe{OV\ -\xc9\x93\x13`\x8e\x9cDd\x83v\x08\x1b2N\xf5\xcf\ -\x07\x00\xcb\xa2\x8fy+\x88\xdc'\x00Q\xaa\xda\xff=\ -\x0e\x00\x00\xae\xda\xd5\xe1\xf4\xa6\x88}\x1a`\xf8l)\ -\x98\x8b\xe2D\x9a\x81\xe0\xe8\xd3\x0d\xce\xb8V\xbck\xb9\ -N\x00y\xb5W`n\xc06m \x1c\xdd\x06\x95\x96\x01\xfd\xa2\ -\x15\xa09\x19\xdd\xa5\xc0\x96)\x09\xeb,\xf1\xde\x83>\ -\xe4\xfe\x82<\x87\x83MU\xc3\xe1\x84\xe9\xbdi\xd0\xfd\ -\xb4\x1e0\xe8\xc1FG\x81\x14/\x0a\xb6x\x11\x90\xe8\ -(\x90\x98(\x90\xe8(\xb0\xd1\x91@L\x94\xa7\xdc{\ -\x8d\xc4D\x81-T\x10\x90\xd1W\xd8\xde\x1b\x06\xfd\x8a\ -\x9f=D\x96[\xd0j`\x1b\xd4\x0b\xb6\x09#A8\ -\x09\xb1\x98\xc3'`X\xb9\x06\xda\xf5[A)\xedm\ -DQ0/\xfa\x04$R\xdeq\xe4\x99\xe5\x00\xa4h\ -a\x98\x97\x7f\x06\xc7\xeb\xeda\x1a3\x19\xf4\xad;\xc0\ -\xbdd0\x7f\x07\xd1FT$\xd8\x98(\x90\x021\x1e\ -\x22\x89\xf1\x12IL4\xd8J\xe5\xc0xw\x09\xcd\x0d\ -d\xac[\x01\xa7\xcf\xd7\xc0\xed\x06,6 \x22\x0c\xba\ -\x1d{\xa1[\xf5\x8b\xaa6\xec\x83{\xc1\x15 5/\ -\x10\x0a\x0e\x90\xc7p\xc6\xb5BZ\xf3\xc60|\xf6\x15\ -\x0cs\x16z\xa2uT\x82JM\x03\x93\x9a\x06(\xf9\ -\xff\xe7\x00HT$\xd8r\xa5\xc1x\xf7C ^g\ -\x1c\xed\xce}0N\xfc\x18\x8e\x0em`\xfbh,\xec\ -\xfd{B?w1(\x85P{w\xb9\xd2\xb0\xce\xf8\ -?\xc5\xe7\x86\x94\x03\xe4\x95\x0e\x80\x98\x8c\xb0~8\x1a\ -\x8e\x8em`\x1a\xfe\x81\xdf\x16\xfe4\xc1\xb2\xe4\x138\ -;\xbd\x82\xf0\xb6=\xa09x\x0c\xe1o\x0c\x00[\xa6\ -$\x18\xaf\xa3\xaa>\xe5\x09l\x13G\x81-S\x12\xee\ -\xb6/C\xb3]\xdaS\xd8\x07W\x876\xd0\xee\xde\x0f\ -\x12\x19\x01\xa2\xd1\x80D\x84yd\x22\x93\x110\x1a@\ -\x0cz\x90\xb0\xb0gw\x0a\x90\x82;\xb6\x06\xd2\xf7o\ -\x80~\xe9*\x98\xa6~\xca3\x98\xe49\xd2\xcd 4\ -\x0d\xdb\x84\x91\x08o\xdf\x0bTj\xba\xff\xe7\x03\x1e\xcd\ -\xa2v\xfb\x1e8;\xb4\x81\xbd\xff[\x8a\x04\xa0_\xb8\ -\x02\xfa\x85\xf2A3\xfev\xb3\xddq%p\xff\xff\xd3\ -\xa0\x03`\x18\xd8G\xf4Cj\xfc\x1e8\xde\xea\x9a\xd7\ -\xbd\xf1\xc3\xe7S\xe0l\xf9\x12\x5c\xb5\xa57\xa2\xd2{\ -\xf7Jt\xc4\xb5\x04[R\xd9\x1bJ\x0d\xf2\xad&\x90\ --V\x04\xe6\xe5\x9f!c\xddr\xb0\xd9\xd8\xf13\xa7\ -\xa0\xdd\xbe\xc7\x1f\xf8\xe9\x18)N\xfa\x0c\x00\xda\x1d{\ -A\xdfI\xf2\x10q\xbf\xee9\xf2\xdc\x90j\x02\x9fF\ -;\x803\xae\x15\xd2\xfe\xde\x0d\xdb\xd8a\xaa\xdc\xac\xb3\ -\x045\xed\x12\x02\xfdb\x8f\xcb\xbd\xfd\xf5\x0e\x9e\x95\x87\ -\x10n7t\xde\xdc\x00\x8e!}<\xf3y6\x91o\ -9\x00\x17\xc4d\x84u\xc6\xfbH?\xf4;\xdc\x0d\xb2\ -\x16\xa8!\x07\xeb\x9cIHM\xd8\xcf3\x0d\xcbA\xb7\ -z\x13\xa8\xd4t\xc0\xa0\x87\xa3O7\xc9:\x86e?\ -\x00V\x1b\xd8B\x05\xe0P\xe1\xaf\xa9\x84\x10\xc8\x00y\ -\xbf\x0aP\x0bW\xed\xeaH\xdf\xb7\x01\x96\x85\xb3\x80\x88\ -0\xe5\x1bT\x80-^\x14l\x99\x92\xb0\x8f\x1f\xa1X\ -\x97\xca0C\xff\xe3:\x00\x80]\x86\x00\xa8\xfb\x0f\xfc\ -N&\xb6Q\x83\xb2m\x9c\xfa\xd7\x1f@\x00B\xd3\xb0\ -\x0fx\x0b\xa9g\xfe\x84#\xc8\xb8\x08)\xf8\xa4u{\ -\xbf\x1e Q\xca\xd1\xbc:oh\xba\xbbZe\xb8\xab\ -V\x92\xacc\x98\xb7\xd4\xc3\x05J\x15\x87\x93\xb3\x7f3\ -[\xba\x04l\xe3G\x80-_Fu\xffr\x9d\x00\xb8\ -\xae\xe2\xa6\xf0\x9c\x19U\xa1\x00[\xbc(\xcc?-\x86\ -y\xf5R\xb02\xf9\x83\xd9\xd2%`\x9d6\x1e\xe9\xbb\ -\xd7\x225a?\xd2N\xed\x82\xf9\xab\xb9\xbc9_\xb7\ -a+\xa8'\xa9 \xe1a\xb0\x0f|[\xf1\xb9\xcc\x89\ -3~\xfd\xbe\xb3\x93t\xa4\x12}/\x19z\xaf6\xd0\ -6\xa8\x17H\xc1\x02\xb0\xce\xfe\x10\xa9\xf1{`\x9d:\ -\x0e\xd6)\xef\xa9{\xc7*\x15r\x9f\x00\x229\xee\xcb\ -Q\x85\xb3\x97w8/\xe0\xe8\xf4\x0a\xd2\xfe\xde\xed\xf7\ -\xbf\xf3\xc1U?\x16i'v\xc26n8\x5cM\x9e\ -\x07[\xbe\x0c\xdc\xd5*\xc3\xd1\xa7\x1bXNn#\xca\ -b\x85\xfe\xfb_\x01\x00\xf6\xe1}\x95Y6!\xd0y\ -\xb9\x863@\xd4\x91~\x85\xd7\xd7\xb0a\x1d\xa4^<\ -\xe0q\x105\xe8A\x99-\xd0\xfe\x168u\x8e\xbb\xc6\ -s0\x7f\xf7\x05\xd2\xfe\xde\x9d\xfb\x8a\xa0j\x8d27\ -;\xaa\xde\xa8^\x80\x9aO)\xd2\xcd\xd0\x7f\xfd=\xb4\ -\x9b9\x91\xd0\x0c\xe3\xb1\xafG\x86\x83\xb2X\xa1\xd9\xfe\ -'\x18\xefvv\xf4\x95D\xd0\x82\xf4u\xba\xc5+a\ -\x1b\xda\x17l\x89bpt{\xcd?\xcf\xcbA\xb3\xf7\ -\x100\xfc\x1d\xb8\xeb\xd7\xf6\xe8N\xa4\x04i\x96\x80\xca\ -0\x83\x84\x87\x81\x84\x87\x01N\x17\xf4+\xd7\xc00k\ -\x81l\xb0\x8a\xbbfU\xd8G\x0f\x82\xbdGg?\x97\ -\xcau\x02\xa8R\xb7\x16\x9e\xab\x1f\x8b\xcb\xa7\xe2%w\ -\xbe|ZA\xa5<\x86a\xf1w\xd0/\x5c\x01J\xb0\ -}\x9d\xa3c[\xb8kW\x03\xc5\xb2\x08\x8f{\x1b\x1a\ -\x85DZ\xcc\x8d\xdb\xd0\xad\xde\x08G\xef7`\x1f9\ -P\x91\x00\xe8\xb3\x17\x00x\x92@\x91\x22\x85@qr\ -!@\xa3\x81\xf5\x83\xff\xc26n\x84\xdfZ\xa9\xdd\xbc\ -\x0b\xc6\x0ff\x82\xe1l\xaa\xcd\x85\xabvu\xd8\xde\x1f\ -\x01g\x978\x912.\xd7\x09\x80\xa2i\xcc\xdc\xb0\x02\ -I7n\xcbnl\xf44\x81J~\x08\xe3\xfce\xd0\ -}\xf3\xa3\xac\xb9\xd5\xf9\x86\xc77P\xb3\xf5\x0f\xc5\x9f\ -\xef\x83a\xee\x228\xde\xea\x02w\xedjp\xb5n\x0a\ -\xcd\xee\x03\xb2u\x99\xdbwA\xb1,\x08M\x83\x8d\x89\ -\x02\xc3!\x00G\x8fN\xb0y\x93VP\xc9\x0f\x116\ -\xe6#h\xd7o\x91m\x8b-\x5c\x10\xd6/g\xc2\xf5\ -\xbc\xf4\xb6s!Y\x05D\x17.\xf8\xd4\xff|*\xf9\ -!\x8c\x1f\xceFT\xb5\xa6\xd0\x7f\xbe,\xa0\xad\xdd\xe5\ -\xdd\x91\x5c\xbb\xef\xb0\xea\xf6\x99+\x89\xd0\xad\xf7dA\ -\xb3N\x1c\x1d\xb8\xb2\xdb\x0d\xe2\x1b\xa9\x82\x11\xcb\xc4'\ -\x80J~\x08\xdd\xf7\xbf\x22\xaaN\xeb\x80?\x1f\x00\xe8\ -\x07\x8f\x10\xd1\xbc+\xc2\x06\xbc+\x99]<\xdf/\x03\ -\xe9\xdbwazo*\xa2\xab\xbe\x04\xc3\xbc%\x8a\xae\ -^$\x8fTen\x00\x00\x06\xb0IDAT&\x1a\ -\xacw\x17\x15\xa5\xd1\xefl\xda\x08\xe6\x95\x0b\xe0\xf6\x12\ -\xbfa\xce\x22\x80\x10\xb8^\xa8\x0fG\x8f\xce\xb2\xf7\xb1\ -\x15\xca\xfa\xe7~\x9a\x93h\x1a\x00\x98\xf8\x0b\x88.\xdb\ -\x00a\x83\xdfS\xef\x90B\x08t?\xadGT\xbd\xb6\ -\xa2\xe9'\xdf\x12\x00}\xf3\x1f\x98\xde\x9b\x8a\xc8Z\xcd\ -\xa1_\xf4\xad?\x96_\x09l\xa9\xcc%!}\xfd\x96\ -t\x9d\x8a\xe5\x90\xb1v\x192v\xae\x81\xa3{'\xd8\ -\x86\xf6\x01\x000\xe7.B\xb7f\x13\x00\xc02\x7f\xaa\ -\xec:\xdf\xa7\x04b\x8e\x9c\xccQ\xdfC\xea\xfe\x03\x98\ -\x06\x8eED\x97~~\xc2\xcaw\x04\xc0\x5c\xba\x86\xb0\ -\x01\xef\x22\xaa\xa6\xe7\xc7S*\x92[rAL^\xbd\ -\x86\xd5\x06\x8a\x93\x82\x16\x00@Q\xb0\x0f\xe9\x8d\xb4\xa3\ -[\xe1\xec\xd8\xd6\x7f\x99\xe6l\x82mzo\x1a\xe8{\ -\xc9 \xd1QH\xdf\xfe3\x9c\xdc\xed^\x8d\x06\xd8\xc6\ -\x0c\x81m\xecP\xcf\xe9\xfce\xc1\xbd\x9cJh\xb6\xef\ -Ad\xfd\xb6\xd0\x7f\xbe\xec\xd9\xf7\x08\xf2\x81I\xb8\x0c\ -\xc3\xbc\xa5\x9e\x11\x98\x9d\x8d\x9b\xbcs\xb2\xd0#\x87\xe8\ -u\xb0|\xf3\x19\x1cot\xf0\x5cH7\x83\xb9\x9f\x0c\ -w\xa5\xf2`\xabd\x8et\xeaQ\x0a\xc2\xbb\x0dB\xda\ -\xd6\x9f@\x8a\x16F\xc6\xa6\xef@\xdf\xfc\x07\xf4\xc3G\ -pU\xa9\xe4WA\x1b\xe6,\x82VE*\xdc,\xbf\ -\x86\xd9\x02\xd3\x07\xb3\x9e}\x0e\xc0\x9c\xbd\x88\xb0\x01\xef\ -\x22\xf2\xf9W=\x0e\xa2\xd9\xdc\xb5\x8b\xf2nhM\x0c\ -\xfaL\x01\x8da`\xfe\xe5\x1b\xff\xcf\xd7\x1c9\x89\xa8\ -F\xafB\xbbq;\x00\xc0]\x9c\x9f\x16\x829q\x06\ -\x11\xad\xbb\xf93\x83\xb0eKy\xb2\x85E\x84\x81\x89\ -\xbf\x80\xf0n\x83`T\x91u5'\xf0\xccr\x00M\ -|\x02\x0c\xb3\x17A\xbba\xabb\xba\x95`@\xfb\xb6\ -\x99e\x18\xb0\xe5J\x83N\xbc\x05\xdb\xf8\x11~\x07N\ -\xfd\x8f\xeb`\x1a2\x1ep\xbb3W\x12\x12\x9b\x5cj\ -\xe2\x13\x10\xd1(\x0e\xee\x17\xea\xc3]\xad2(\x96\x05\ -s\xe24\xcf\x0b(\x14x&\x09@\xbb\xe7 \xb4\xeb\ -\xb6\x80\x8d\x0c\x87\xb3K\x1c\x88\xd3\x01\xcal\x05e\xb3\ -{\xb2vX,\xa0\x1cNPi\x19\x9e\x1f\x95\x9a\xa6\ -\x9aH\xa8\xc7O@%?\x04)R\x08\xae\xd8\x1a\xd0\ -%\xde\x82\xcb\xab\xe1\xd4m\xd8\xea\xff\xf9@f\x16\x0f\ -\xea\x81t\xc86\xc5\xb2\xd0\x1c:\x1eT\xd6\xd0\x9c\x86\ -\x06\x9e\xfc\x01A\xec\xc2\xf8\xf4\xc3\xd9\xa2\x09\x9c-\x9a\ -\x04u\x0f\xc5\xb2@Z:(\x97\x1bH\xcf\xf0\x08\x87\ -V+(\xab\x0d\x94\xcd\x0e\x98-\x80\xd3\x09*5\x1d\ -\x9a\x93\xf1p\xbe\xda\x12\xce\x8em\xa0\xdb\xb8\x0d\xc6\xd1\ -\x93\xa0m\xd5\x14\xfaUkyS\x8c\xcb\xeb[\xc0H\ -\xe42~Z\xa0\x01\x90\x06q\xf2\xaa|\x07B\xd3@\ -t\x94\xc7\x851\x80\xf3\x86~\xe5\x1ah7n\xf3\x10\ -\xc0k\xed@\x22\xc3\xc1\xdc\xb8\x0df9?\xcb\xa8\xbb\ -\xc6sp\xbfP\x1f\x80'U\xcc\xd3\x0aj\xb75\xf1\ -\x18@Igf\xfe\x17<\xd0\xff$!\xb2A[\xc0\ -\xcd\x22\xf5\xdaQ\x90\xc8p\x18f/\x84q\xca\xa7\xbc\ -z\xc4dD\xfa\x8e\xd5p7\x88\x05s%\x11\x11u\ -Z)\xfa\xf1\xe7\x18(\x0a\xb6a}A\xd9\x1d\xa0R\ -\x9e\x80~\xfc\x04\xd4\xe3T\xcf\xd4\xf5$\xd53\xedq\ -\xa0\x01\xa83\x00\xfe%\x00%\x10\x82\xb0a\xe3=.\ -[\x00\xf4\x0b\x97\xc36a\x14l#\x07B\xbbk?\ -4\x07=\xbb\x9d\xb8kU\x85y\xf1l\x8fk\x19!\ -0\x8e\x9b\x1a\xba\x9f\xef\xed')V\x04\xd6q\xc3\xa5\ -\xcb].\xd0\x8fS\x81\xc7\xa9\xd0$\x5c\xdaD\xed\xb2\ -\xdex\x8b\x02~\x0c]\x0f\xff7\xa1\xff\xe6'\x98\xfe\ -\x9b\x19dI\xc2LH;\xb4\xd9\x13\xa9k\xb5A\xfb\ -\xc7\x01\x902%y.\xdd\xc6I\xb3a\xf844A\ -\xa4\x5c\x90\xa8H\xa4^\xd8\xaf\x98K\x90\x10\xaa;\xb5\ -\x95\x5c\x89\xd4\xd9\xb4I\x90\xceE\xf4/\xe0Q\x1bG\ -5l'\x0a$qW.\x8f\x8c\xad?\x81\x15d,\ -\xa5\x1f\xa6\xc0\xf8\xeeG\xd0\x09R\xe9\x87\x12\xb6\xb1\xc3\ -`\x9d\xf1~\xa0*\x16\xc6`*J\x11B\xb0\xdbv\ -s\x05\x05\xf4\x0bU\xe7\xfe\xa7@\x08\x22:\xf6\x81\xe6\ -\x0fi\xf3-\x89\x8a\x80}h_\xb8\x1a\xd5\x03e\xb6\ -@\xb3\xef\x10\xf4k6\xe5}\xd4\x91A\x8f\xd4s{\ -e\x03H\x08\xa8\xa5\xad\x0de\x86Q\x84\x10\xec\xb1'\ ->\xc7\x12\xfa\x1c\x9eQ\xbd@v`X\xbc\x12\xc6\xb1\ -S\xf2\xba\x1bY\x82}\xe0[\xb0|9K\xaa\xc8\xec\ -bQ\xb9\x9d\xa9l\x12\x0d\x00-\xf4\xe5/Q\x14\xc4\ -i\xab\xf39\x98\x1b\xb7a\x08\x91J67\xa0\xffv\ -\x0d\x98K\xd7\xa4\x8a>kg*\x9b\x04p\xac\x81\xb4\ -\x9eL\x00\xa8cR\xb5\xf3#(\x96\x85i\xe0X\xe5\ -$\x0c\x5c0\x0c\x1c\xbd^\x87[!\xb7r\xc8\xe0v\ -\xc30c>\xef\x12\x05\x9c\xb3\x1at\x9f\xf8\xce\xfd\x04\ -\xd0\x1c\xe5l\x14\xa1\xbb\x02P\x9ft\xee\x19\x86~\xd1\ -\xb7\xfe\xa5\x9d\x1a8;\xb6E\xda\xb1m0\x7f=/\ -\xa8|\x82\xc1B.?\xb0\x1ct\xeb\xb6\xf8s\x0eP\ -\xc0\x03\x9ab\xbat@q\xff\xb6)\xbc\x9e\xb64\x96\ -\xbaC\xb1\xe8\x08@9\xdf\xe83\x0c\xfa\xf2u\xd5\xd6\ -8\xd7\x0b\xf5\x91\xbek-2\xd6.\x83\xbb\xba'\x15\ -=-\xe1z\x95S\xc8X\xb9\x00\x19?.R\x15j\ -\x06\xc0\xa3\x8b\x98<\x07\x14\xf0\x00,^i\xae/\xc5\ -K.(\x22\xd5\x96\xa6\xb2\xa7@\xb9\x9bP\xc0\xb9\x9c\ -\xe9\xf2\xff\x18\xdcn\x84\x0d\x1a\xab\xe8!\xe4\xaeS\x13\ -\x19\xbf\xadB\xfa\x9eup\xbd\xf4<\xaf\x8c\x16x\x11\ -\x07B\xd0\xdcB\xaf\x87\xb3k{\xa4\x9d\xdc\x09\xe7k\ -\xedT\xdd\xa2\xdd\xb9\x0f\xe1\xaf\x0f\x1c\xdd\xd2TV\xe4\ -\xc3&\xf9\xf4V\xfa\x0a\x97-\x06]#\x02\xcc\x84'\ -\xd1t\xbe\x81a\xfe2h\x8e\xc9'\x12b\xcb\x96\x82\ -e\xe1,\xa4\x1f\xfc-3\x87\x0f\x07\x94\xc3\xa9~\x09\ -\xa8\xd1\xc0\xb2rApD\xe0\x8d\x08&E\x0a!c\ -\xcdW\xc8\xf8q\x91t$\xb1\x00\xda\xad\xbbGI\x05\ -g\xca>\xb9\x03\x8a[Z\x1b\xca~\xc8\xb2te\x80\ -\xfa\x0a\xf9\x80\x10\x98\x8bWa\x9c\xf9\xb9d\x19[\xa2\ -\x18,s'#-~\x0f\xec\x03\xde\x92\xffiO\xd4\ -\xef\x0dl\x1b=\x08\x8en\x1d=\xfe\xfa\xaa:\xc8\x88\ -\x22\x8b\x9c]\xdb#\xf5\xef]<\x174)\x10\xe0\xf9\ -\xd3\x80h\xb7\x0cJm\xf8\xf6A\x5c\x8a\xb0Y\xf5q\ -\xa0\xd0\x92\x80\x8a\xa5\x81\x0a\x04\x88\xc2\xb3bJv\xb9\ -\x10\xd1\xfcuhN\x9e\xe1]&1\xd1\xb0\x8d\x1d\x02\ -\xdb\xf0~\x80\x8a]\xd4\x98\x8bW\x11Y\xb7\xb5b=\ -\xb6LI\xa4\x9d\xda\x05\x12f\x02\x93p\x19\x11\x0d_\ -Q\xb4\x19\x90\xf00 int: int: The exit status code. """ app: QApplication = QApplication(sys.argv) - app.setWindowIcon(QIcon(":/icons/cpdctrl-gui-logo")) + icon_path = resources.get_resource_path("cpdctrl_gui.resources", "icon.png") + app.setWindowIcon(QIcon(icon_path)) AppConfig.initialize() window: MainWindow = MainWindow() diff --git a/main.py b/cpdctrl_gui/main.py similarity index 94% rename from main.py rename to cpdctrl_gui/main.py index e9f275a..bc6e571 100644 --- a/main.py +++ b/cpdctrl_gui/main.py @@ -9,7 +9,7 @@ if __name__ == "__main__": sys.path.insert(0, pdir) sys.path.insert(0, path.join(pdir, "cpdctrl")) print(sys.path) -from app import init +from cpdctrl_gui import init if __name__ == '__main__': import sys diff --git a/app/ui/__init__.py b/cpdctrl_gui/ui/__init__.py similarity index 100% rename from app/ui/__init__.py rename to cpdctrl_gui/ui/__init__.py diff --git a/app/ui/main_window.py b/cpdctrl_gui/ui/main_window.py similarity index 83% rename from app/ui/main_window.py rename to cpdctrl_gui/ui/main_window.py index caf0c58..13b443a 100644 --- a/app/ui/main_window.py +++ b/cpdctrl_gui/ui/main_window.py @@ -1,14 +1,19 @@ -''' app/ui/main_window.py ''' +''' cpdctrl_gui/ui/main_window.py ''' from PyQt6.QtCore import Qt, QTimer -from PyQt6.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QTextEdit, QLabel, QDialog, QToolButton, QStatusBar, QFileDialog +from PyQt6.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QLabel, QStatusBar, QFileDialog, \ + QVBoxLayout from PyQt6.QtWidgets import QToolBox -from PyQt6.QtGui import QIcon +from PyQt6.QtGui import QIcon, QPixmap +from PyQt6.QtWidgets import QDialog, QDialogButtonBox + +from .. import resources from .widgets.menubar import MenuBar from .widgets.toolbar import ToolBar from .widgets.metadata_input import MetadataInput -from .widgets.measurement_settings import ScriptSelection, MeasurementSettings +from .widgets.measurement_settings import MeasurementSettings from .widgets.plot import Plot from .widgets.device_select import ListChoice +from .widgets.about import MarkdownView # from .widgets.treeview import TreeView import multiprocessing as mp @@ -43,26 +48,28 @@ class MainWindow(QMainWindow): central_widget = QWidget(self) self.setCentralWidget(central_widget) + self.create_toolbars() + self.setMenuBar(MenuBar(self)) # must come after toolbars + self.setStatusBar(QStatusBar(self)) + layout = QHBoxLayout(central_widget) central_widget.setLayout(layout) - self.create_toolbars() - - # Add Widgets to Window - self.setMenuBar(MenuBar(self)) - self.setStatusBar(QStatusBar(self)) - + # Left: Toolbox self.w_leftbox = QToolBox(self) + self.w_leftbox.setMinimumWidth(300) layout.addWidget(self.w_leftbox) - init_elements = [("name1", "val1"), ("name2", "val2"), ("interval", 0.5)] - self.w_metadata = MetadataInput(init_elements) + metadata_init_dict = AppConfig.MEAS_CFG.get_or("metadata", {}) + print(metadata_init_dict) + self.w_metadata = MetadataInput(metadata_init_dict) self.w_leftbox.addItem(self.w_metadata, "Measurement metadata") # Measurement settings self.w_measurement_settings = MeasurementSettings() self.w_leftbox.addItem(self.w_measurement_settings, "Measurement settings") self.w_measurement_settings.set_value("interval", AppConfig.MAIN_CFG.get_or("interval", 0.5)) + # Right: Plot self.w_plot = Plot() layout.addWidget(self.w_plot) @@ -95,10 +102,12 @@ class MainWindow(QMainWindow): style=Qt.ToolButtonStyle.ToolButtonTextUnderIcon, icon_size=(24, 24)) # Top Toolbar Buttons - self.topbar.add_button("meas_devices", "Devices", QIcon.fromTheme(QIcon.ThemeIcon.Printer), self.vmdev_connect_from_dialog) + self.topbar.add_button("connect_vmdev", "CPD Devices", QIcon.fromTheme(QIcon.ThemeIcon.Printer), self.vmdev_connect_from_dialog) + self.topbar.add_button("connect_leddev", "LED Devices", QIcon.fromTheme(QIcon.ThemeIcon.Scanner), self.leddev_connect_from_dialog) self.topbar.add_button("meas_start", "Start", QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart), self.measure_start) self.topbar.add_button("meas_stop", "Stop", QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStop), self.measure_stop) self.topbar.add_button("meas_save", "Save", QIcon.fromTheme(QIcon.ThemeIcon.DocumentSaveAs), self.measurement_save) + self.topbar.add_button("app_about", "About", ":/icons/cpdctrl-gui-logo", self.app_open_about) self.topbar.add_separator() self.topbar.add_button("app_exit", "Exit", QIcon.fromTheme(QIcon.ThemeIcon.ApplicationExit), self.app_exit) self.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.topbar) @@ -185,7 +194,8 @@ class MainWindow(QMainWindow): raise ValueError("No led control device selected") self.topbar.disable_button("meas_start") - self.topbar.disable_button("meas_devices") + self.topbar.disable_button("connect_vmdev") + self.topbar.disable_button("connect_leddev") self.topbar.disable_button("meas_save") self.topbar.enable_button("meas_stop") self.w_plot.clear_data() @@ -250,7 +260,8 @@ class MainWindow(QMainWindow): self.proc_measure = None self.led_script = None self.topbar.enable_button("meas_start") - self.topbar.enable_button("meas_devices") + self.topbar.enable_button("connect_vmdev") + self.topbar.enable_button("connect_leddev") self.topbar.enable_button("meas_save") self.topbar.disable_button("meas_stop") @@ -264,6 +275,8 @@ class MainWindow(QMainWindow): self.set_status(f"Data {i:03}: {tval}s, {vval}V, {led_val}%") # update the plot self.w_plot.update_plot(tval, vval, led_val) + else: # measurement might have stopped after max N or script end + self.measure_stop() def measurement_is_running(self): return self.proc_measure is not None @@ -291,11 +304,28 @@ class MainWindow(QMainWindow): """ self.close() - def settings_window(self) -> None: - """ - Event handler for the "Settings" button. Displays the "Settings" window. - """ + def app_open_about(self) -> None: + dialog = QDialog() + buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok) + buttons.accepted.connect(dialog.accept) + dialog.setLayout(QVBoxLayout()) + # show the logo via a pixmap in a label + img_path = resources.get_resource_path("cpdctrl_gui.resources", "logo.svg") + pixmap = QPixmap(img_path) + pixmap = pixmap.scaled(128, 128, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation) + label = QLabel() + label.setPixmap(pixmap) + label.setAlignment(Qt.AlignmentFlag.AlignCenter) # center the image + dialog.layout().addWidget(label) + # show about.md + dialog.layout().addWidget(MarkdownView("about.md")) + dialog.layout().addWidget(buttons) + dialog.exec() - def __del__(self): + def closeEvent(self, event): if self.measurement_is_running(): self.measure_stop() + # save the metadata + metadata = self.w_metadata.get_dict() + AppConfig.MEAS_CFG.set("metadata", metadata) + event.accept() diff --git a/app/ui/widgets/__init__.py b/cpdctrl_gui/ui/widgets/__init__.py similarity index 100% rename from app/ui/widgets/__init__.py rename to cpdctrl_gui/ui/widgets/__init__.py diff --git a/cpdctrl_gui/ui/widgets/about.py b/cpdctrl_gui/ui/widgets/about.py new file mode 100644 index 0000000..981dafb --- /dev/null +++ b/cpdctrl_gui/ui/widgets/about.py @@ -0,0 +1,13 @@ +from PyQt6.QtWidgets import QTextBrowser + +from cpdctrl_gui import resources + + +class MarkdownView(QTextBrowser): + def __init__(self, path): + super().__init__() + self.setReadOnly(True) + self.filepath = resources.get_resource_path("cpdctrl_gui.resources", path) + with open(self.filepath, "r") as file: + content = file.read() + self.setMarkdown(content) diff --git a/app/ui/widgets/device_select.py b/cpdctrl_gui/ui/widgets/device_select.py similarity index 100% rename from app/ui/widgets/device_select.py rename to cpdctrl_gui/ui/widgets/device_select.py diff --git a/app/ui/widgets/measurement_settings.py b/cpdctrl_gui/ui/widgets/measurement_settings.py similarity index 94% rename from app/ui/widgets/measurement_settings.py rename to cpdctrl_gui/ui/widgets/measurement_settings.py index 431d870..364dd85 100644 --- a/app/ui/widgets/measurement_settings.py +++ b/cpdctrl_gui/ui/widgets/measurement_settings.py @@ -1,11 +1,13 @@ from PyQt6.QtWidgets import QWidget, QRadioButton, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QFileDialog, QLabel -from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox, QLineEdit +from PyQt6.QtWidgets import QFormLayout, QDoubleSpinBox, QCheckBox, QLineEdit, QGroupBox + +from os import path from ...utility.config import AppConfig -class ScriptSelection(QWidget): +class ScriptSelection(QGroupBox): def __init__(self, parent=None): - super().__init__(parent) + super().__init__(parent=parent, title="LED Script") self.layout = QVBoxLayout() # Radio buttons @@ -57,8 +59,11 @@ class ScriptSelection(QWidget): def load_file(self): # options = QFileDialog.Options() - file_path, _ = QFileDialog.getOpenFileName(self, "Open Script File", "", "All Files (*);;Text files (*.led)") + last_dir = AppConfig.MAIN_CFG.get_or("tmp_last_script_dir", "") + file_path, _ = QFileDialog.getOpenFileName(self, "Open Script File", last_dir, "All Files (*);;Text files (*.led)") if file_path: + dir_name = path.dirname(file_path) + AppConfig.MAIN_CFG.set("tmp_last_script_dir", dir_name) self.file_path = file_path self.w_script_file.setText(self.file_path) @@ -85,7 +90,6 @@ class MeasurementSettings(QWidget): self.l_form = QFormLayout() # - script - self.l_vbox.addWidget(QLabel("LED Script")) self.w_led_script = ScriptSelection() self.l_vbox.addWidget(self.w_led_script) # key-value stuff in a form diff --git a/app/ui/widgets/metadata_input.py b/cpdctrl_gui/ui/widgets/metadata_input.py similarity index 89% rename from app/ui/widgets/metadata_input.py rename to cpdctrl_gui/ui/widgets/metadata_input.py index f9441f7..3e9465d 100644 --- a/app/ui/widgets/metadata_input.py +++ b/cpdctrl_gui/ui/widgets/metadata_input.py @@ -8,11 +8,14 @@ pairs. The value may be text - line edit, float - qdoublespinbox and int - qspin """ class MetadataInput(QWidget): - def __init__(self, elements: list[tuple[str, str]]=None): + def __init__(self, elements: list[tuple[str, str]]|dict[str,str]=None): super().__init__() + # set layout self.l_vbox = QVBoxLayout() self.l_vbox.addWidget(QLabel("Measurement Metadata")) self.l_grid = QGridLayout() + self.l_grid.setColumnMinimumWidth(0, 100) + self.l_grid.setColumnMinimumWidth(1, 100) self.l_grid.setContentsMargins(0, 0, 0, 0) self.l_grid.setSpacing(0) # first row: key value @@ -25,15 +28,20 @@ class MetadataInput(QWidget): # key-value widgets self.ws_elements = {} - for (n, v) in elements: - self.add_element(n, v) + if type(elements) == dict: + for (n, v) in elements.items(): + self.add_element(n, v) + elif type(elements) == list: + for (n, v) in elements: + self.add_element(n, v) self.l_grid.setContentsMargins(4, 4, 4, 4) self.l_grid.setSpacing(4) self.l_vbox.addLayout(self.l_grid) self.setLayout(self.l_vbox) + self.layout_changed() # call even when no element was added def layout_changed(self): - # align at the top with space at the bottom + # add stretch to the last row for r in range(self.l_grid.rowCount()): self.l_grid.setRowStretch(r, 0) self.l_grid.setRowStretch(self.l_grid.rowCount(), 1) diff --git a/app/ui/widgets/plot.py b/cpdctrl_gui/ui/widgets/plot.py similarity index 100% rename from app/ui/widgets/plot.py rename to cpdctrl_gui/ui/widgets/plot.py diff --git a/app/ui/widgets/toolbar.py b/cpdctrl_gui/ui/widgets/toolbar.py similarity index 100% rename from app/ui/widgets/toolbar.py rename to cpdctrl_gui/ui/widgets/toolbar.py diff --git a/app/utility/__init__.py b/cpdctrl_gui/utility/__init__.py similarity index 100% rename from app/utility/__init__.py rename to cpdctrl_gui/utility/__init__.py diff --git a/app/utility/config.py b/cpdctrl_gui/utility/config.py similarity index 100% rename from app/utility/config.py rename to cpdctrl_gui/utility/config.py diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..84328ad --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["setuptools"] + +[project] +name = "cpdctrl-gui" +version = "1.0.0" +description = "GUI Utility for CPD measurements with a Keitley 2700 SMU and an Arduino-controlled light source" +requires-python = ">=3.10" +readme = "README.md" +license = {file = "LICENSE"} +authors = [ + { name = "Matthias Quintern", email = "matthias.quintern@tum.de" } +] +classifiers = [ + "Operating System :: Microsoft :: Windows :: Windows 10", + "Environment :: X11 Applications :: Qt", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", +] +dependencies = [ + "pyqt6", + "pyqtgraph", + "numpy", + "cpdctrl" +] + +[project.urls] +repository = "https://git.quintern.xyz/MatthiasQuintern/cpdctrl-gui" + +[project.scripts] +cpdctrl-gui = "cpdctrl_gui.main:main" + +[tool.setuptools.packages.find] +where = ["."] diff --git a/resources/resources.qrc b/resources/resources.qrc deleted file mode 100644 index 69b2bb4..0000000 --- a/resources/resources.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - - logo.png - - \ No newline at end of file