diff -Nru ukui-system-monitor-4.10.0.0/debian/changelog ukui-system-monitor-4.20.0.0/debian/changelog --- ukui-system-monitor-4.10.0.0/debian/changelog 2024-07-25 15:52:05.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/changelog 2024-11-19 17:11:36.000000000 +0800 @@ -1,3 +1,48 @@ +ukui-system-monitor (4.20.0.0-ok1.1) huanghe; urgency=medium + + * 提交commit:d3e802f8c + * Bug号:无 + * 需求号:#36365 系统监视器增加磁盘详情读写页 + * 任务号:#199505 子 【2024】基础组件组周例会待办&平时任务&OEM临时任务 / 【何思胜】【系统监视器】需要加上磁盘读写详情页 + * 其他改动说明:修改编译依赖,重新传包 + * 其他改动影响域:无 + + -- hesisheng <hesisheng@kylinos.cn> Tue, 19 Nov 2024 17:11:36 +0800 + +ukui-system-monitor (4.20.0.0-ok1.0) huanghe; urgency=medium + + * 提交commit:76dae208 + * Bug号:无 + * 需求号:#36365 系统监视器增加磁盘详情读写页 + * 任务号:#199505 子 【2024】基础组件组周例会待办&平时任务&OEM临时任务 / 【何思胜】【系统监视器】需要加上磁盘读写详情页 + * 其他改动说明:修改释放内存,修改编译依赖,重新传包 + * 其他改动影响域:无 + + -- hesisheng <hesisheng@kylinos.cn> Thu, 31 Oct 2024 14:20:14 +0800 + +ukui-system-monitor (4.10.0.0-ok5.19) nile; urgency=medium + + * 提交commit:a52363f3 + * Bug号:#IAB8QN 【次要】【系统监视器】【维吾尔文】内存和交换空间详情界面存在文字遮挡 + #IAB98T 【次要】【系统监视器】【维吾尔文】网络详情界面布局存在问题 + * 需求号:无 + * 任务号:无 + * 其他改动说明:无 + * 其他改动影响域:无 + + -- hesisheng <hesisheng@kylinos.cn> Sat, 12 Oct 2024 16:05:18 +0800 + +ukui-system-monitor (4.10.0.0-ok5.18) nile; urgency=medium + + * 提交commit: + * Bug号:无 + * 需求号:无 + * 任务号:无 + * 其他改动说明:更新0920weihake翻译 + * 其他改动影响域:无 + + -- Kevin Duan <duankaiwen@kylinos.cn> Thu, 25 Jul 2024 15:52:05 +0800 + ukui-system-monitor (4.10.0.0-ok5.17) nile; urgency=medium * 提交commit: diff -Nru ukui-system-monitor-4.10.0.0/debian/control ukui-system-monitor-4.20.0.0/debian/control --- ukui-system-monitor-4.10.0.0/debian/control 2024-07-25 15:52:05.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/control 2024-11-19 17:11:36.000000000 +0800 @@ -33,7 +33,8 @@ libkysdk-proc(>= 2.3.0.0-0k2.0), libkysdk-proc-dev(>= 2.3.0.0-0k2.0), libkysdk-realtime(>= 2.3.0.0-0k2.0), - libkysdk-realtime-dev(>= 2.3.0.0-0k2.0) + libkysdk-realtime-dev(>= 2.3.0.0-0k2.0), + libkysdk-disk-dev Standards-Version: 4.5.1 Rules-Requires-Root: no Homepage: https://www.ukui.org diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/0035-50-changelog.patch ukui-system-monitor-4.20.0.0/debian/patches/0035-50-changelog.patch --- ukui-system-monitor-4.10.0.0/debian/patches/0035-50-changelog.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/0035-50-changelog.patch 2024-11-19 17:11:36.000000000 +0800 @@ -0,0 +1,5846 @@ +From: nil <zhoubin@kylinos.cn> +Date: Thu, 14 Nov 2024 01:15:32 +0000 +Subject: =?utf-8?b?ITUwICDkv67mlLljaGFuZ2Vsb2fkvKDljIUgTWVyZ2UgcHVsbCByZXF1?= + =?utf-8?b?ZXN0ICE1MCBmcm9tIOS9leaAneiDnC9vcGVua3lsaW4vaHVhbmdoZQ==?= + +--- + data/ukui-system-monitor/en_US/image/4.4.png | Bin 0 -> 34506 bytes + data/ukui-system-monitor/en_US/image/4.png | Bin 34774 -> 36778 bytes + data/ukui-system-monitor/en_US/index.md | 6 + + data/ukui-system-monitor/zh_CN/image/4.4.png | Bin 0 -> 43912 bytes + data/ukui-system-monitor/zh_CN/image/4.png | Bin 18312 -> 42071 bytes + data/ukui-system-monitor/zh_CN/index.md | 7 +- + src/controls/kchartview.cpp | 20 +- + src/controls/kchartview.h | 2 - + src/img/read.svg | 1 + + src/img/write.svg | 1 + + src/kleftwidget.cpp | 11 ++ + src/kleftwidget.h | 3 + + src/mainwindow.cpp | 6 + + src/mainwindow.h | 2 + + src/res.qrc | 2 + + src/src.pro | 15 +- + src/sysresource/chartviewwidget.cpp | 98 ++++------ + src/sysresource/chartviewwidget.h | 26 ++- + src/sysresource/commoninfo.cpp | 215 +++++++++++++++++++++- + src/sysresource/commoninfo.h | 43 +++++ + src/sysresource/diskdetailsmodel.cpp | 82 +++++++++ + src/sysresource/diskdetailsmodel.h | 59 ++++++ + src/sysresource/diskdetailswidget.cpp | 47 +++++ + src/sysresource/diskdetailswidget.h | 37 ++++ + src/sysresource/diskhistorywidget.cpp | 231 +++++++++++++++++++++++ + src/sysresource/diskhistorywidget.h | 54 ++++++ + src/sysresource/diskitemwidget.cpp | 145 +++++++++++++++ + src/sysresource/diskitemwidget.h | 54 ++++++ + src/sysresource/diskviewscrollarea.cpp | 195 ++++++++++++++++++++ + src/sysresource/diskviewscrollarea.h | 42 +++++ + src/sysresource/netdetailsmodel.cpp | 17 +- + src/sysresource/netitemwidget.cpp | 158 ++++++++++++++++ + src/sysresource/netitemwidget.h | 60 ++++++ + src/sysresource/netviewscrollarea.cpp | 59 +++--- + src/sysresource/netviewscrollarea.h | 4 +- + src/translation/ukui-system-monitor_bo_CN.ts | 256 +++++++++++++++++--------- + src/translation/ukui-system-monitor_en_US.ts | 263 +++++++++++++++++---------- + src/translation/ukui-system-monitor_kk.ts | 128 ++++++------- + src/translation/ukui-system-monitor_ky.ts | 120 ++++++------ + src/translation/ukui-system-monitor_mn.ts | 75 +++++++- + src/translation/ukui-system-monitor_ug.ts | 50 ++--- + src/translation/ukui-system-monitor_zh_CN.ts | 75 +++++++- + src/translation/ukui-system-monitor_zh_HK.ts | 75 +++++++- + 43 files changed, 2302 insertions(+), 442 deletions(-) + create mode 100644 data/ukui-system-monitor/en_US/image/4.4.png + mode change 100755 => 100644 data/ukui-system-monitor/en_US/image/4.png + create mode 100644 data/ukui-system-monitor/zh_CN/image/4.4.png + create mode 100644 src/img/read.svg + create mode 100644 src/img/write.svg + create mode 100755 src/sysresource/diskdetailsmodel.cpp + create mode 100755 src/sysresource/diskdetailsmodel.h + create mode 100755 src/sysresource/diskdetailswidget.cpp + create mode 100755 src/sysresource/diskdetailswidget.h + create mode 100755 src/sysresource/diskhistorywidget.cpp + create mode 100755 src/sysresource/diskhistorywidget.h + create mode 100644 src/sysresource/diskitemwidget.cpp + create mode 100644 src/sysresource/diskitemwidget.h + create mode 100644 src/sysresource/diskviewscrollarea.cpp + create mode 100644 src/sysresource/diskviewscrollarea.h + create mode 100644 src/sysresource/netitemwidget.cpp + create mode 100644 src/sysresource/netitemwidget.h + +diff --git a/data/ukui-system-monitor/en_US/image/4.4.png b/data/ukui-system-monitor/en_US/image/4.4.png +new file mode 100644 +index 0000000..b99b28c +--- /dev/null ++++ b/data/ukui-system-monitor/en_US/image/4.4.png +@@ -0,0 +1,136 @@ ++�PNG ++ ++��� IHDR������������� pHYs�������+�� �IDATx���w|TU���ϝ�2ɤ�����H �R\�� ++*��被�모Xt�ȗ���Q\YvP�R-�BB�gf���q�1&��I#��_3w�=�̘��7���9��i����2�������6����!�)���C�S����XZz��QPP���gϞm��Zv<���=S�geߪU�֬Yӭ[�ٳgGFF�-==}�ر����������@c���TNNΑ#Gj4�́����������Ƒ#G�Ν+"�v�r:�.l�p��Z��ũ���?��g<�b7n�e�]����>((�,����{^���4b�����V㧢�\�͛7ϛ7o }����<S�A����C}�76������P�������S�5M���,**JIIٺu�={D�����^���}��gk��p8V�\y��ᰰ�/�л_����e�+NY�/����{�����K�,Y�~��|�����-�Z��{p8�G�6>\�����Pݩ�}����k>���v˖-}��7F���U�:�h"�U��[~w`��ڎc�Y�6��2�&����<y�����{VV��>U�����4ڮ��ÿ���Du͏n���?u�����Y�&�lt�=U����i���W�q����sR�.�W�ΐ�ju��s�gj"����W���� ^(�(ʜ9s���˒�UU����ӧ�h�jժ��J=z�gZzu����֭ۿ\\ܑ#G:u�t���;v v���ڶm��ӧE������3����@#}�&�˄A����Dm}�z�%f���+/QT.�N�S�V9��9����#����zu��j�'��QG���Jhc�D}y�*zHH�������o���|�]w)ʯ~���{/11QD�.]Z;N�{y�N��IOOOOO_�~��%K{챱c�6(�ڵk֬Y"b�XV�XA����L]3�hrƛF�&�3G�{/5 �2i"�Q����k������Uha����h�%L�{��[���MfƏ�ǩ������N�:���S�N�{�eee"r�^q�;v,((زeˁ���fϞ�����۷����<��C��_~y��� �6�����_����kU���q|@-s�u���bMF��x���T-ʡ�7�4��S�"2���lm������i��~��ݹreO�ޱ�@?y�SW\�fU�������/7o<��긶?[��P�:���$"�S�W��/\c� �W�+�P[���M�v�]nh�4�lkl,�Z��ٳ����'��^z�%=K͘1����g�Y�f}��w/����w�]�,URR2g��p������W7�;���3(sJB�/w���~y}�X,����k����U�1uS����kU\.3?sM�iz�&sJ����?J��g{D8����X5-O����j����_ǘ����?�_��w�eR����ʵ�L�vI���sH��b�cdC����Uw��>R�#�����7�UM��_��N��r�으�{��/"999�<���b۶m"b�X���?U��XQ�K/�tժU>>>��MU�_|����"2q��{キA_���ɱ����oQk���r�{���M73�Ȑ���-��<���W�}�٤H��ʏ��8���g��b�,�:�(�v��4��k�Y��'��S�v�@ӧ�jT�r���ot�?͢?���*�=�:���v�{`� ++��.�]������┈DDD�q������ddd�������������裏V�Z%"|��g묀��a@����_�χ߹�M�9=*-O�R墺̡t����Uu�r$2�K�ʪDD}%%W�Re�1uO�&"�.MDr��C���e�Wq�$-6K�²����K�O�N�D�c�iDoS��;%"�������y����_���>|8::��Wן�HHH�o������c���_G��"R3�A�εx�.qؔ����F�)���/ɹ��D)YE��t ���S�vT"jm�����?���Mwǘ|,ʴ���Pݘ��wQ��O}|�����7X|Z|��!��BCC���u�։�̙3,Xp��7b!^RR�g��[o�խ[���������HJ�ֻ�"�^�7���}�v�s=o�Vʲ��ݔN!��UD�w��k&�"�IQ��UuP�<�,"9��*[�!P�9���ަ�W��R�K���ϛq*77WQ��}g��O;v�ĉyyy�f�<x�ԩSǎ\�����̙SXX("cƌ>|xCG����V&tW���j��_eՏ�L��~���8ג�ݓ���&�uR��P3[��ܪz�@����-�_c���e�`��ߺ},�#\�,�N��M""�3��,�l�I��Sٚ�%V��&U��kU2�������|MD����Z�r�� ��=h Y�t�k����矋���<h��n����o��w����/�p��a����ۿ��;���E���y����n�Ind���A��7Z^�ʽ<�%"C#���Kh@����A��$��2��i�����3�2��"��]���E����HS���������a�sט<���+�Wf�0�I�#Q �2i��w����3_�Iyt���)�fy�2�ٗ�����6��={n��v ++ ++����QRR��~�;���ޯ_�����������j��iھ}�V�\�z�������?���Q===}�ر��Y�f���;"2lذ�{��H�=V�ZP�?��hE嚏U�s*RA�f1) Xi��[ ++ʴ�R���-�eZh��(�V��T P��H��\3������I^��X�Z{���V.\/O "6�-**���+�2lذ�^zi�֭���g�Ւ%K�}�Y������Yj������w�)"�N��������78���R"���,%"�tTj1��%,���X�& <[���f�_ &�"�f)�V��4mŊ�뫮�����j�ܹ�<�m۶x@?��矯\��,�t�����^����f� ++ �ŋ���O���@�y'Nm۶m߾}��ɓ'�0$$�����,�ӫI�) `���"6w�\����?_UUe|$���g�8���:o�<��СC/���}�&N���8z���x-Z���4W_}��Q�D��<K����q꧟~�6mZVV���l�^x��U�������g��E]��C�Zj�7����c��.\���ڠ����4T#�TUUաC��ϟ� 7�>}Z?�ꫯV��>�l�2a����+--�����_��СC��g���g͚%"/����� ��@�Wݩ��ҧ�zJ]VV���q��ђ�O}SLLL��]PP��IZ�h�ڵk��!C����i�������[��4eʔ�|�=��^�:33sӦM�7o���+t:��@��+N�\��>��ΏL&ӌ3�N�ڱcdž^;88����z�'RRR�}���ml6۫��ڹs����O�����{n��ᡡ��<���\�f�u�֭S�N�z�1b�E]ԡC�F_~�ȑk�ꫯ>��S�gu��rˬY���t&L7n�֭[srr/^�,���]g���̲��RSS���|||:u�Ies������8���ym������8��`q ++�������!�)���C�S��������!N��B���0��=���ʚ���-��߿gqw ++�������!�)���C�S��������!N��B���0�8��`q ++�����ũ]�vmܸ������?���?z����E�5�,���V�aqj����;w�~$333%%��WݳgODDDC�j(�˵t��)S�,X�����,-KJJv�����Oo۶��G���3 �Seee�w��ׯ��nݺu�����9�O>�$>>~� ���,8K�'N�[�n˖-���M=*��p��c�39t�Є �V���Z�r�_~ٹsg���7��>�裲��ɓ'_y��֭��Ξ>}��h�6��k�����.*((HHH���r��O<�Ĕ)S֯_���o���C�gdddX��5k�0`�̙�6mZ�nݠA�x�???IIIy����㯸��o��d2-[�lѢEQQQS�N3f�<Q��"2dȐ!C��s�=�������w�����ѣG��G}�f͚�zhҤI�'}�����n��{�����wo����~����RIHH���ϣ��D$66v�ĉ&�IӴ�7>��S111��r�����<+''g� ���3gΌ���� ++gΜ�˕����wGGGϝ;7>>~Ŋ��������I��ѵk״��:������/��S.�kӦM���K�,y�ᇇ3n�8���|��w�=���.�8q�7�|3`�������X���ﯽ�Z��!";v�9r���'�xbܸq�]w]�Ν����tVtt��ٳG�=a���3f��7�?~����Ed��ͣF��������{�M7�����'K����W .,,�����@�U�8u�رK.�$ ++��ru�ҥF�����~�ȑ#G�|�7����f�7u�VM�֮];a����رcǀ<'Z,??p���N��γD�j��/l6��f�����u���W�1cFzz����t�-����b�,�����;w�~����ED%%%%5���{�̙�'O�~���/���['M����1d�9|�����=y�N��:����+���W^����������r8���iii;v��w��h�zݝ�4mÆ z� 3f�ʕ+������[�ͤI�>�����T��}��Q��ZTTT���_z�o����W�M�:��g�Ә1c�o߾w�^�˕��������{뭷�^����l����\rI����tzNNNFFFee�>�]����P��S���!!!���"�(ʣ�>���0f̘�{�o߾z����w�'O�<y�aÞy���L����_�O�r��6l�袋�y��g�G�=/^��s� >|�ԩ���"2}�K/�t�ʕ���;���<��UW]�hѢ���*!!�����P4M�q����ƑU�Vi�����g#)�R����*++�'��v���>�ॗ^2<�i�VXX�p8L�_bbII��n�1N�������qV��N}���Æ �q��p��(��LYJD~�ᇱc�6p� �(Jppp�,%"d)���t�uw*''',,�x(),,��������hUww�^q ++���=h}���8����!�)���C�S����x3NUTTTTT�����u�t��=�бc�����t��\.��?�Ν;��FӴ�� ++UU����VTT��n��}��7�7o^yy�����˛q�[n���5j�w���'�TUU�Ǘ/_�iӦ��5M۾}���Ȓ%KbbbbbbF�9}��~������+((�~��r-]�tʔ),(..���̘����QUu�����_].�~�cĈS�LY�~}�~JJJ���@�T�-��ny�i� ��L��=L���n��O^~��iiiK�,9t�Ћ/��(ʂj�֬�뮻nΜ9N�366v���k֬�ԩS#���O>���_�p� ,X��/V�t������{���}||D$ `�ƍ.�+!!aƌݺu8p��rϞ=�� �����r��k��As^��W������g<�n����_|�����߲eKll��|��7n�������O�<y�������O����;wnVVV�����AAA:t��ok2����D$%%ey��v�?��}�℄�7�|sڴi?��ɓ'�s_{��)S�����QI��t.[��;��:u�������=�n۶����~��WCCC��L&�����ۼy�СCE�ȑ#?��m�������W���z�)����W��>+<<|ذa���'N�y孷�2��.<x���t��ُ<�ȸq�"""���СCUUU\pA~~��w�=w�����+V�ȶmۺt����_x�O>������Ν;���`y��Ȩ�[nnnnnn�ΝE��pt��5--�s��{쮻��ի�����ܿ��={�.]1x�`�xzz����ܹ���={�o~����Ϗ=m��hW����q:t萝�]�`iiihh��^+"���zjҤI&L����/�<t�PQQQii��/�ܵk��>�lԨQ�_���t�M�<��]w�u��w�H~~~TT�;3�������w�mݺ588x����q�n��R��< .,,�ҥ��<��S111+V����CBB����˗/w�\������///����+��t[^^ޥK�iӦy���mB��NM�V����ZV���Qc�Ӄ>0q��>����n� �w����ȑ#�y������7���Vbb�u�F�9r��3f�����z�ԩ����>��w�}'"UUUiii�;w��O���"�Y�WTT�������o���磏>�x�W�x�իWw����_֏o۶mĈ"b�Z�y�]�v�t�M6l��o��8��+N�=L�2�毅�kS��v�8����w�^ϔm]hh裏>��g��رcٲe�����K����k���5: �۷��ٳ���K}Vdd�W\�?���SU��{�ꪫ�-[v�}��'��枩�Bhh����>O���<--�cǎ�GS�N�Z�>��|_�DEQ����O�***:r��`�>}�z����?��s���9��pިW���e�Hu�T�ʩ�Y#ϸ�OD��w��9gΜ�o�y�����n�������������:mڴ�_�S���=z�s�=������3f��������r�������233KKK���+������]����d]�N��ޡ��ﭷz�겲����_r�%ݻw�?ҧ= 8p���o���>������~����˗_s�5"�������l6�Hnn�ʕ+KKK���۳gO�a"��h'�\��_����>��iӦ��o�����,//���cbb����w��-��L�6-..�믿����n�-55uÆ =z�X�x�s�=7|��S����;����/�fͺ��+=���+�����o_v�e�}�Yttt��O����q饗�\�ry��x�=��ٳgǎ"RZZz�WN�4��W_��k��ٹs�Q���n�;..nܸq�_~y�^�Ǝ������=J�>5� ++x���.))q8F��i�VXX�p8<�JJJ|}}�d桪jYY�>m�N%%%v��#�����k֮]���[����<����@+���߈��pe_��fsPP��NE�1ͼ�c2��n}���Ǝ[=K�����g� ��h?�����A��`�@��6�N�R�����S��������!�)���C�S����x3NUTTTTTxjiz8p !!�v{����C;v��GN�����zϞ�UUU�/q���ݻw}�h�VQQ�v��<�v�����Hzz��E��o����ix3N�r�-111�F���;>�䓪�*�����7m�T���i۷o///���W_}u�7�SSScbb:��}�G֮][���;/^��^�bEFF�9G�����+���x��Ǔ��j�mժU��z�=�ܳs�N�`~~�s�=w�-�,[�L�&333&&f���8���ߊȷ�~3bĈ)S��_���%���q�q��V�~q�]��v��ݫ\�^��v�������'�ܰaÜ9s�m����O뷔,X0s�� �W�^�O�����#G����\.��ݻ={�|�����������lx&N���k�n�,Xp�<����o���7�|���^�ӟ�4g�}{�'�|�k/���?��z�jO�U�VynP��'' `�Ν۷o����͛��h�֭Ço����Z�z�)�wok��KY���j����{�L-�v{xx��_<��-[���Ɗȇ~�q�F��ə?��ɓ�ϟ���\�ĸ���s�fee�o�u�f2��6����^z�]�D���ӕ��ݻw?u��������;k֬�[�~��7K�,q�\O?�tQQћo���c�UVV���U�V�y�s���駟<��Z�����ɓ���3eʔ��������III����ի�СC/�䒴���'O����z�={����ۗ-[�y�h2������Yӵk�_~_������pDGG����� ++����� �IDAT ++���DdӦMӧO�5k��ի].W}�����֣^qJ;�T�� �<%<<|ذa���'N�a孷�2��.<xp��A��ُ<�ȸq�<�|}}� ������mۦN���wߕ��&%%���+88���������~x�]w 80''����&�I�~xܸq�&M�X,+V�ضmۃ>��������~��S�S?V}�111_|��Ν;������گ_?}c�.� ))���Xo|��WoݺUD���;nܸ��pO?N�s���{��Y�tiDD�����㱱�'N4�L���?��<���������z����HVE�СCvvv���������^{���wb��ʞz�I�&M�0�z�!C�;v,--���jĈݻw?~���'F��i���G���&�i�ȑ"2x�����WVV���~�a�Ed͚5����Ǐ�~M�����ӧV?ޭ[��/�x�ܹ%%%?����(((����+..���e�]6k֬�3gnڴi�ĉo���ݻ����˗�\������������رC�4MSU��r���������@K���)��U�z����9+##�S�NՏ<���'N���<;.\�p���5�4�/�p���ǎ?~��l;v�ѣG�?ޯ_?O����� ++��rM�:u�ȑ#G�ܹs��Y�ǧ�~z�ĉ;S��7�|�O�>�7o~�W�{ク����@Ϙ�Y�v�]۩S�aÆmݺu�ΝC���O@@�+����o�^��{��/����TTT�رCO}��y�7.\x��<x�,_���N��S���*Co{�wP��n}�9OIKKۻw���� }��G?��;v,[�L?�t���^{M���ѳg�cǎ}���z@�袋8������k�g5�m����s� 7To�q��%K���� ++ ++�~��r�X�bܸq6�mܸqS�Lپ}{dd�����;jYYY:tp8�S����g�}��nП֦(J߾}O�<)"�?~��f�?3f̧�~z�UW͘1���<�����oe��f��ϖ_Zf|i���b���a~~~rr�Ν;�̙s��7Wz�v�?��㬬������h�4���o�СӦM{������.��n��Y�F�կ_��7fffv���,#����߿RRRQQQ``��ɓW�XQXXXUU�g���q�ꫯ{�G}�l6'%%鷲�,Yr��)��2t��m۶UTT�ٳ�C�����ܹ��͛���V�^}�m��L��z�#�O�o������~����˗_s�5"���ߏ=Zop���;v(�2t�Ъ�*� 0���Vxy���/�l���x4q���9�����o����l���/����#�XDdڴi�'O���=3�,KLL̾}��u�&";v�ӧ����>��,�M�6w�\����_����/?~���cǎ�۷�~#����G���zJ?��[o�9s�+.���=z<��3,;v������'M�d2�,X��e�ܹ'N��[�_4 `��͵�VZZz�W�l�~��]w�u�_���ްa����bY�l��?,"�����@+�T�a�k�$n������p(��tWї���E���BUU�R�������%"���6���M�JKK�����ѣ|��K/�T�`II��j�~!�����jk}u2��5&*5��ř�3�V#��X�'"���R"��?���3�'��hA�}w ++������V�����jjw��7���@s�������q ++�������!�)���C�S��������!N��B���0�8��`q ++����4M���r��Mw 6������t���{�*�X�Yee���m@@��`rrr@@@hh�������� ""���?99YUU1�L���aaaf��z�EEE������M�D�8���G^^�ѣG=o�V��ѣk���͍���X,N��K�.�z�ҏ'''GFF�q������á���v��������OUղ��'N<�zP��� S��q ++��4�˥(�ȑ#��@UգG�v��5**���h���aaa�����8��Ç���]xᅞ�:t�ݻ�����}��%%% 4��iNN�'����i^�V�)���\.��j���9S�����եKq8�###�z�RU5..NU�A��x��3�������?]iiiee��Iyy����m6[ddd�n�L&�L"'N����t:EIMMu���#$$�F���2��f�Z��v�����z�'N��߿F&s�\eee�����W�q����g�#G��HtttUUUnn��q ++��4MӜNgaa���:u��\�?��X~I&V������633��r������'ffffff��v{�9�999�:u�_WTT�1�cǎ^�j�)���z��ݽ{w��&"))) �:u���&�I�4�[UU�?�s�\]�v 8r�Hvvv��z�:u���RU���2)))66vĈV�������x���z��={?~|�ݺu��*�N���(���DijF�z���t:=o].W��z���QQQAAA'O��^G�d2鳲G�].W^^�����z.9b���q�ر��X/V�"N���P��]UU�����Vo�p8�YP�ۂ���� ϧv�]��ԫW�������:��2}Vnnn�����۷o�A����{�{ ���@3(((8t�P�=���].W|||@@�>����V�u�����v���ɓQQQ����iO�v��)99�cǎz ������WU���"55�n��������={�g������Oݻw��箕q�)���䂃�{�왚���� "!!!}���'KUTTx�� 4�СC����X,��=zdee%$$0@DrsssssE��� �ڵ��l�������K}���j ++ ++:r䈪���DEE9o};���/��&���wU��l�9RYYi��N?v��f����~P�4��3U��įa���h>V��z���T#�����R����䄅��8����V�N���8��U��b�)����g<���h [�W\ZPZZXUU�D���h:6�o`@���kk�t �S��O������3� ���j����;�t�}���V߹S��O��_��/^�������Tg�j¹S%e�EEyd)��p��{haQNii��:�_�*)��,)��@����_\Z������*�/���V����Q(�������!�)���C�S����ԫ�giiaIYQS���y����A�ꭞw�o]����f����)��a�;�u�Ћ��h)ɩǼ�s����!N��B���0�8��`q ++�������!�)���C���������DUt�������Њ����!N��B���0�8��`q ++�������!TE���U����*:���TE��hE�S��������!N��B���0�8��`q ++�������v������Q���������"�)���C�S��������!N��B���0�8��`U��@�CUt��������`�U���Z����!�)���C�S��������!N��B���0������ݡ*:���ATE��0�������q ++�������!�)���C�S��������!N��BUt����P��� ����@Ut���V�8��`q ++�������!�)���C�S���������*:��hw����`U����*:��@+B���0�8��`q ++�������!�)���C�S����P���;TE��0������P���!N��B���0�8��`q ++�������!�)���C���������DUt�������Њ����!N��B���0�8��`q ++�������!TE���U����*:���TE��hE�S��������!N��B���0�8��`q ++�������v������Q���������"�)���C�S��������!N��B���0�8��`U��@�CUt��������`�U���Z����!�)���C�S��������!N��B���0������ݡ*:���ATE��0�������q ++�������!�)���C�S��������!N��BUt����P��� ����@Ut���V�8��`q ++�������!�)���C�S���������*:��hw����`U����*:��@+B���0�8��`q ++�������!�)���C�S����P���;TE��0������P���!N��B���0�8��`q ++�������!�)���C���������DUt�������Њ����!N��B���0�8��`q ++�������!TE���U����*:���TE��hE�S��������!N��B���0�8��`q ++�������v������Q���������"�)���C�S��������!N��B���0�8��`U��@�CUt��������`�U���Z����!�)���C�S��������!N��B���0������ݡ*:���ATE��0�������q ++�������!�)���C�S��������!N��BUt����P��� ����@Ut���V�8��`q ++�������!�)���C�S���������*:��hw����`U����*:��@+B���0�8��`q ++�������!�)���C�S����P���;TE��0������P���!N��B���0�8��`q ++�������!�)���C���������DUt�������Њ����!N��B���0�8��`q ++�������!TE���U����*:���TE��hE�S��������!N��B���0�8��`q ++�������v������Q���������"�)���C�S��������!N��B���0�8��`U��@�CUt��������`�U���Z����!�)�0��˴��-= ++���8�U^ �*E-=���8����&��_�9�����ShIZ�)�'@�&N��0�Z��}\� �������GUt���Ӈ�V�Oe��S4�oK��^P�sQ�f��>A������]�*:���.q��jYf�EU��4���<��&�_���,�jN|K��F"N��hy���_D�'P����p��h$�ZN� �����Jީ���E�B�ѲO�o����_�(WeK���� N���'��D�P-/�e��@���B�e��L�����f�y���"N�eh9'�?���V_��}������h��v����Pk�̒���* ��� U�q>�����y�Z�-ŧ[p<��v���h�ܻ�%0���i{�u�-&sK��>P��S�X��bcq��-"N�h� ++�(Rl��:������mq ++-!/�W��t_�Mh����`q ++-!/Q|j� в���h��0�8��eNjŷ�A�ǡQ�������cʯ硋��JaZK��C�Sh y���Q�q{[��������)�3�,���ga��lf�;*�T������U�ѶY��T��:?��Vk����̀��h˴�D�l����+ܧ2'��4�@�*:�6-'^�5����'P�����!N��i�'{�)>�����m q ++�M�Kߺ������_���ܼ#������Jq��j�D��u!��������t8K����)�@�B�B��r�v=��lZ�7W[���ԈSh^� �w������a��-�*:�UXʏ��ܥ5�{(��[����r ���@Ut�a��4�Zw����4���4�ن�h����6�U�m����mT���6E�� ��d���6+/Q�g[��3��䱸��f��|����<�1��,�N����Qn�X|���7PrO6�h�����Q��s���j�M?����8���&*>g�^��dQ,>Zqfӏ��/ N���o=�N��o;��� ++��K~���Է·Տ����mU��L����}�g��^�E3���Dm�Q��'���M2���V�ƪ��Z�Ҥ���oTEG�ޟ+|��O_5�r��&BUt�M� ����3[�d�Ҝ����A�B3� ++S���)�/Xcq��- N�9h)�$JC��X��h#�Shy��٭�W���}�iF��7������6��'@�a�>�@@�Bs�2���ްs|������D�B��=Y��e<,>��R^�4��k����Щ ���M�_It�՞{t{ex�&��ݢ*:�sY�f����Og�5�5�����*:��T�j h�?���PWQ�����FUt�5��biز���j�J���z�)495���e}""��jy,���v�)4�F,��Y|EuJe����7��� ++R��q ~!l5�h�ShZZq�X|�T�E�)V6B��r�)4��D�n��V?-���F����д����5�|�@6B��rTEG� ++N�kQW�{(���&�y�:��TEG[b-LQ���>]3�(�J�U��!�@Ut�%��L��э��."�X_�ɟ��k�����4[L6#YJD�f��Z1�������X�'""��Weq��#N� i��bm�n}��Hv�7��@� N�)�0T%ADD�C�Oyc4��4 ����sB�q���U���#����ShBZ�����Q�C�j��j�j���r�{֖�y�,_M�6/te�K�)/��@�*�����~&ې���e}�ғ-=��͖}$�j/kl=��,�T%�. ++�2��h�����6��,�w]K��Qޭ�^ς@��*��Ԑ�"���r)��|���[zPm��(M�����lvkA�W�L�����?��-/��Z��)��f����DU�&�\�|o�鮊�D��]~��?^��m����V��Vi~�6�d�Y�8t~����i?�Uv(aQ�t�h5��䗦1�����ݪ���U�G���eLO����������dxiZ��e����� %٢��d�N���iɻո�ډ-�E���]_��)��v���o�i��-2B�� qJD�5��;k�Z��Gt�f�������j�dSp7o���ô�D�CoouԠ�>���z|����Õ�E9�b%��v�K�������9H��qJ��mVD���x�g�h���/_Z^�H�j��Bq����}�����{���Ok5��n�5���Q��A���(J�K�z��Z��^(a�)eW��{�'HEH�S��^�15��� �^zҧ3�J.k-�me���'H��:��m�ՠ�����_�� ++R�n���OS�ݦ��u�*(Wl7Gw<���3T�NP����ߪ���D�j�f�>��}ܛ��Sv��y��G��Ci�nH�^���ߪU�ywl���{��S��z��:"��?�Q]�p��Nړ����vQ0�;r⽰�q5�o������Ω���v,2���X���������^���g�?�];�YK�����o�zb��g��W���1]�{V1լ������}�0ݛ�s�~H;�K�|�w�3YL=/w-��;�hڞՏ�*���sS��.�zr�T��6�'�My�Zdž��>�G:;��>oU�����N)�ޮ0a� ����J��]-���e 6�)����;��'�o� ++��ݢ�oQz���&��yꦞ�Z��]��nxZ���4b�ҡ��e�1��� �����ʪ��M�~9W;���#ƫ�nZZq�v`���VU�DP:E+�+���{�%�4���'P�M0���IK����aS�1b��~����r�����9�Fq�zO���+~�Mz��6Niqkݻ�U�v �n�����u�����q������k�4����<�����z%r���iӠ������-�K=��/�K��JX/��LJ���֪?~,�Y���t�O̍�Z�M�&���W�=)}��~�hԽj�?7����.�8"� Ž��'��*��%?����q(��6����8��~����D�"��O�Q��Jp��9��v퍼�p�I ���Up��s��W���i�?Q��訥��ŭ��u��� �IDATGg�E7)�5�4g�$��wh� ++S���e�ܥ��'�Wiq���HqtRz���_��:ϮEE����, 2����ǫ��t>J�7�@K*˕�,�ؿy��^��g)]�5����J�I��wL1���Zh��$�{K��r�\�ŭU:_��i'g�hZ�g^ee5W���ڴ�����P��S �RB{����@�R�T�m���8�")�*�Lj��F��2���TO��X�S�O�s�|-��*,����sR��;S�M� ��eQO}' �HN�w_��lZy��劦)]�����.�(!�-5�Y���/)�0] ���*���@s�jER���t�.C�.�L9�g��W$�'%��%7+�Ԝ㖻���nь���j�NI�V+�S#��L��HS�1J�Q�뵭�Eu��M6] �����:��y�<�%��f�"Z-�'-y���SK?�t裕�z�(Q�J�Q�WW:���w�qQ���-�8��K,�X��{�5�c�FM41Fcb�����b���ڍ؍F�Dlt�pp�������-�a4��~��gonnv�������[�l96����K@�J����Ak*�m��j2�5 ++��-D��l�v��^�NSp�l��b"�����w�cr֧���8���1�XT����tO��nRt�D�z��u�t������:�L�*~ʨs���͆����Υ��k�،L�e��MB$;'�������F��K@[C�� |È��� ++�~ ++S���� '_B�UAi/����jV�"{»���B+ߴDO���w�}�e0��3ck�X�R�řl��l�e6�.!�"$rV�Fp������Nɪr Y¿Ё�nQk����.Y�3�]w�����8��D@ǿy���V��d�bӮAvH�@�vN�� ��4�*(���¿Q/��l��k\{X��bz%�+k�ij�g�*-��Tn~�FSR�?�;(�d�5��"rԐYOK�\5(4���$x�XG���d��x9�TX��qMsc;���D�ԯb����I��W\��>�Q�^ ��59˾%�-�M��8D3��C)�e��Q�RG4ta��h� ��*�U>%܃��ad`w�6������)$<@�HػWw9f�������c&�C �vd�6���><����ꔄ̛p�{Y'��4��^ ���;|����R�m��n���X&� ++5|k�A$z�X�l� 6�*�v�e-��!qY~l�<V_��V �|§5Љ���f&� s�'�/��%؈M�N����UU��$��)�yү3��@BH�;'��U�@�����:%�-���'�^�W>ݖaA�� �ЀBC�&���\�YW;p�c]�`ϔ��y��eչlI��bU9P����5��ޝ�{����G8zro�{�Я� ++6�s�p�$��q%>�JN�C&s��Vv��%�S�����O�4 ++��Օ�����2�6˲��,�,�K�J�U��%j��T�.��t:�^+0��d�=��cub�JX�tFo�� �l $:R�{-i�f�E���Q"{���������Qn�"��%�����I���ƣ^gIOKT���`�q0d2��HPO��R�_,�6�U��檉���z�*V��yP���BN<�u��y���ߣ���;����������$�ެĉe�,������X���?gPns��~�Rf�)} 蔬AMx4#}ZZn�"���{��1Z��,�l7��~�O���Y]�8���fA���5��X ++�R�{�/!t%`P��0hXc)5�̓Q�IIA͒P����EI)��J�B)!���!�B;�1K��h �-fb���1A�X��`����bbXLcaX�`1k� 3k1��,A�@ ��%��&(����� R��r�@��Ͽ~�_���|>����e,�X���e��X��c��,f��X`����%��&H�%(�E)��fI���la2��;�| ���� �{��1,0,��,����0�6��)i����*��J��*�v�4��$P���� ++hh��H�"X�dɜ[�*�����;�X�����շ���_��O�?/�ʎ��ӛ�{��;�����=�d�Ȟ�B)�@(%�RH��J��MØ�ba,�la,��a���a��0�k� �E04Xh���B���Є��d-��$i43z��[h���1���2��.5�*�@e��&a��R��R3M� #���NNi�����)�=i�: �ńN�ꄬVd�Ҍ��X���������)�ZD�"��@��-J� �% H (� �$H �?��l�. `�w�ZL`1??cM`1�3����Y�w��@ ����%�/�� ����s�aY0��e����`Y(~ʤ]���,Av. q"�./�ˤ�J��4 ++��~�����,X�1��D0&�b��K��"30��$$� $E���z�����!�B�E��(ul��Uj�b=�����J��fDA�M�B%5<�s�MYΦl'K��Ea!hao����H(��� �ba��0i ����l�����B{�y��8�#} ���MH���f�j0��Qz5����T�AE�`(e�¾[�@ɝ $˝$w�<ߐ8�%Y�g3���]>�z��F�����e���p ++����K�%��m�{�,�@HD���U)%��l�_��3��=��f�<ҫ�]��@,}53?���Z��[r*�ɁQV�&FB$d �̜E��X��,S6YϋI�~M I��nά����H��ն�M����������L*��������5U�&FB,d�{R�ΎLQ53�П�EkRB8�������פܜ��牆������l"��X���G�����R |-��̜Oz��H��B�R����n3�!����mU����per����Z�UB8��궱Z�ޮ�'Ջ^h٤��Q��/tz[�b_��R ��f�R���R�/�����&B$���hd�S��EO��&���Me��ޞ�k��p ++����KT ++�H*�`0�B!�0���Q�Va,C8�M�ZSl4V��!�B��!I�v��c|��#�B!�z��,�z�qD!����p ++!�B�&N!�B�e4sss ��>TX3/N�T���䴴4���?@!��C����痖���C��ׄN�KHHx١Ku���������F�1''�E�I��y�B��˲������EY,��M�QXX���C��M&���O��U�Hɛ���TZZ���G`` ˲������|�5C!���#;;;??�y�掎������ �a�<yR�n]�J������X�2Y�%*�Œ��_���*�:�Ni����Ҁ��� ���-##�)�B�_�e٧O�zyyq��T*�J��PPP`6�}||�������!77�:��X,III ++��$Igg瀀��H�EEE))):����>00����-������42�, @.������T�B�nnn4M@FF�V�uqqy���V�uuu ++ ++�( ++�L&SrrrAAEQNNN|et:]bbbII�P(������%�ڙD^�p���%�����b��L&��~�!�B�|��h4:99��z�Vkoo/ ++@�� ++�B>�J�*������O�4nܘ$ɜ�n�K�R����z�����������Q������Q�n]�L�P(�����z��A�������hZ�h�&�)??_�V��������L�\�����aÆ$Ifff�y��1�4k��h4���S�p�h4����F�B��^����J���i�����n4����A�g��z=M�NNNE9;;s����\��888���8;;s����?����@aaaIIIhh�\.��Dr���B� �E�\4RTT�R����U*UHH�/% ++����2���\z�:uj���V8��O��?r\"B!��xf���h߾=EQIII���...$IZ�� ++�0e��|||�J�͛7������)�b���� ���X�������,��!G�V�������dA��j>��{v�����=`ȅ_\��������۷o���������j rz\-��w�%"�B��M��W�י���f�X��>><�����M���d���0ooשּׁ���X�V�u��B�s������\z��L"A���*�j�X��pR���G۶m�ݻg�Xj�eT�Z�T*�(� -))��d�5{!�B�9�Db p!M�f�������b�[�GQ���o�6m���ɡiZ,_+r����^fꕽ�=˲��{��h���WVU�e�*��mb�X�V��Je;��;���ᑑ�!�J�Fc^^>ևB�{P��㓑�agg' ++���e2�D"�H$R�4%%��߿��P��{zz�b&>>�������`0�,� m���?~��������l6ԫWO,שS'##C ����,���cgg����-g����}���������&&&��攔.]��=z������ޞ�jq����N���8� |||jwB!�^s~~~f�����,��d�&M�p�������w�ܡi�I�&֫|��ꚑ�����nnnܓw���f�9---55�\\\�f�@ hذ!A \�U�~}�$�5k�������M�4�z|������Ǐw��@ ���Ǐ3C���??%�vD�N0�����3�L$I�$t�B�߉a��Tf���PX��n��@Q��3��^/ ++˄G�^|�%*�˲\ze1���]�w�{�p ++!�B� V�p ++��#�B��)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6�p ++!�B�&N!�B��)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6!X�}�u@!����)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6�p ++!�B�&N!�Bل��Z��o�B�L&�e�BB�_�����B�Z)��߉ksj�iC�bc�S�`�R!����1���S!�B6�8�®)�B����`�B!��M0�B!�� �S!�B6�p ++!�B�&N!�B��)�B!�`8�B!d�WNm۶-77��O�<ٶm�0g�B�����B�k�z���O ��iӦ���ŋSťܽ{w߾}�Ǐ �N �f���]�t���0óg�6o�<i�$��������-[�|���NNN�����;vL�4�I�&�6m���:t��`���ϻu�֧O�S�oߎ��^�b��a�ӧO_�r%%%�M�6� jԨ���#G��9s�a�����#G�t�U�V��Ɗ+(�R(��틍�uqq�ر�СCi���������2dH�����,�~��74Mϛ7� ++ ++ ++�_����н{w�D�111���+��D"//�Ν;��L&kРAxxx@@��� �E����nݺ}��\RRRnYXX�]8 ++��ƍiii�7�ڵ+w�^�~=++�?��={:::�^�?w�\jjjÆ �v�*������֪U�Ν;s�+�����2eJPPP�}����V(ӦM��篩T���� ++�.]�6L �^l�V�^����{�n�HJJ������/i_��q Qqqqxxxhh(�Xa�>�z��@ �ڵ�������G�zyy����;w�L�#Fpw��=y�d\\\�ƍ�u�֥K� �fV xzzv�ԉ�U��I����x���G��)ǎ;��Z�����7�V�=���d����ٳg7jԨI�&������� �,˞?~�ҥܧJJJ._��m[,��_��U�V~��L&���KKK`�֭���<x�q���ӗ.]jgg���{���V�Zq/ ����;vlNN��ɓ{��q���O?��b��exU���/���gNMM=t����� ;;{��ѱ�����{��;w��l�������^�zq!�ĉϟ?ϗ���>|��cǎY�aaa����V�Z�v-�\�vmܸq999��p�B������c�}[.�oܸq͚5\!�O���_�?g4��gΜy��1{{�_~�e]��ڷoߧO����^�zӦM���O�<y��U����9��ى���<y����7~���1bРA'O�<~����Vf��ɟ}���~��[�n��}!��u���I�&���1m�4�5������6m�X,�h4�G�NOO���Ç���ׯ_���p�ʖ-[N�:�e;x���)S�ԩ3cƌ���%K�p! ++����߿{��2�l�������R��)�ŋ�5k�%%%�O��~�eه>{��^�z��*�h��{���fWWW��z�>..N�Ӆ�����ԸJ赥�j�ϟ߲eˉ'V����y���s��)�s�ʕC�թS�:w�<f�{{{�a���?cƌA�@�n�JKKe2Y�~���Ν;�v��ѣ�m944��o��zhڵk7p��˗/w�ڵ� ++�����ׯ���r�W�\�?���f͚�M�@۶mǏ���Q�~}����=z��Q���?w�֍{ٹsgww�!C��k�ny�������o@� �{�)S��l�r�\'���˦M�&L����p�B�ìA�ӧO�8q���sQQ���Çn}tgΜ�X,7n ++�cƌ�go߾=�;;;�%K�L�>�|��Z�>u�ԧ�~�y��)S����"ζm�|}}W�Z���S�N"��{+???))�`0�hт�+(((,,��������t͛7�z�*�����~�����C�f��b��b!�eل��gϞ�����Ź��)�����S��߯S�w�"�/�s�N�qc�~�֭[e �S�F�1a��P(�/_�W�^����W�ZհaC���_�m?}�4&&���?粭X�bݺu��@���\.�w�҅���ξt�R�Ν_���p(-**�СCz��bcc�w��7Ff��������O�81y����׳,�����'O^�lYtt�{��UPP0u��;v�۷o�ȑ���6z�X,�+V�L�y����eL�6m���O�<)���[oY��]$$I6n�8&&��R"B&�UV����ӧOGEE�{www����:���@5K�i�_�~�-��b9r�Ȱaø��������$I���[spp(...����w�ҥ�o���seJ$~@P������$����7.�] ++�UPP ��U*�9x�`TT�P(��XlggWf_,�fff���U8�~����}�j4����P����><z�h>h�J��dtt�~�駝;w�7�������������}��իǏ�u�U��N�81hР�._����>cY�СC;v�X,.LMM=z��ҥK�>}�d��N2//����V�T/��z�q��xxxp�Ce ���onn.�$Y~��l6/[���w�mݺu�}�_�~���\�u� &M�DDD���5�ɔ��h��V���S�5JLL�w�^xx��S��z���ӧO���o��Ѯ�����QQQ�[�y���ˮ]��b�ݻw'O���ߴiSHH��L�Ν;�o߾t���98�zظq�ɓ'[�l���W�N�w�}w�ڵ7n��f�������n������~� _|�E�~�ƌ���]Y�yyy�Pf����߅��@�K0�͑������!C>|(�H�5kf= ~�����믫V�rss�-��h4����ه�{���$٤I�p�Ѩ��Jettt�-���f�O?��������lٲ2�ܼy300��J������+�F���0{���L����ɴ|�����N�:�5J,s�]�|�P(|��iff����+��ϟ?߳gO�XܧO�+W�X�NX�p!_Tbb��m�K��m۞8q����l6s}�C���R�f͚����8cƌ}��͞=��̩��_~��5k:v�h6� ++A\�4M<x�s��3g��:AG�}����Ç�$y�֭��� �xt���t���5�����>�裎;&&&Ξ=�L!���tcǎ�4XKKK;w�ܬY���IIIM�4�.7%i��� �IDAT���\����R������Z�`��`x�葏�7��2�|�����Ϟ=���w���֭[�/^4hwu���ݻ���� ñcdž �5��?'z���ѣ������7n� I��ի\���'O�\�x���"�Y,�ѣG'%%]�x���0��f���x`f�s������}����-�q�����Ϟ=[Y��P}�n���z=�UX�*�E��������.]6l��0G�R����t����bIMM k߾��ѣ;t�0~�� ++�OQ���������W��/]���˲j�����z�9����oܸq�̙\ί��jϞ=�/_��㏿��������ʕ+۷o?q�ijg��ٳ��xxxxdddTTT��Ϳ��[�Z���u�9�٬R�N�:ՠA�������#G�p��C�]�+ߙ_\[�ݜ~~~2��ڵk���c�ٳg�[܌=�P�u"V�����~~~:t����===��I�.]RRR��s�� 4��������w�5�O)��* ++�aV�^���Q�uMKK[�z�_|���[�x�b�Ν�����:���Y� 6p�LDGGs)2��s��ݺu{뭷 ++ ++ ++v����b��ϝ�С����}}}�j=4���ղeK����ӳg�T*�0��8��;w��c|�L��X�x���KJJ�����F�f͚��w���b�800��!I�����ao�HԧO�=z�ܹs���|WM\�RAA�u�FNNNHH����+�B%����Ç�?�����{o߾m]�ȑ#G����?x��F�q�p���6l�i��ٹ�V����j}Իv�ruuutt��8�����v��̙3O�:�}���s��7n\xx8�322���߿��m��ݻ�Mp\�jש^PP�}��w�}���O�0`@�>}.]�$�J���͛7�u��0}�_���x��gϞ|7~ZZZZZZe�YM�-8w���� ���ʹ���Jee����<==����<��ŋ�/_.� �/�p�+WZ��e��-[~��GK�,i۶�ĉ.\�O|� 6H$�;vp�V�-ZĽk=�װaC~��_|�`��z�)�m۶>|8�lM�x�{����"##[gݡ�M�4������ԠA'''���������"�J� �� ++��aڵk�Æ �D��qz�����j��\�^�����Yzb�X,��` ��4ݥK�a��/e����i�ƺ�J��9r�����x�"##7o�ܴiS�� ����帺��#w"��nݺ���U�R�3,aaa|�������u,����m???n��JJJ>����S�r�Z,�o�$I�D"�HD"Qpppaa!�. ++-K�8��h��X,]�v]�D"���;v��"##_3����ںuk��_��j��̛7o�̙s���իWek����hѢ�̾�� \X�H���f���w�С����͛�����!"�O���4cƌ�ӧw�ԉK��������疼���}����z�QQQ,�ѣG�=��������@�^��M~�(��m����~��H$�+[υki+�Ѳ]�{���O�><��� :t�ĉ;v����o�駟�4=nܸݻwH�ҽ{�r�)��>}�ƍ�ԩ��㓙�I�dPPw�Z���I�����n֬Ys���իWe���4��GM�<�/F�q�ر9s�L�4���=33��z������gΜf6�<PY�$I~��&Lpqq�ҥ�F�پ}�����Tx����`�x�ȑ7nL�8������뙙��#�UKIIy��Yrr�u�&L����З_~Y�^�{�4������R��̙����u��q��d�7n<|�p�������ϟ�f��� �m�DQ����ȇ������ܹsF��:���R�u�V�ӱ[�n˖-�����k�$ə3g�?^.�w���l6>|�h4~���F�P(��������<��TLLL�V����]�0L��;u�~���[�>\�V_�~��lÆ ���۵k'�d2Y��͝��V�\�������S�����lْ{$���� �@///oo�G�����d2�={�{�����X�`ߛ�w�ܡ(��w�ّ��|�֭[8pƌs�� P�T �c�z�>55�a�R�w��6m�T�ƕ�l ++�:u�ԡC�2�BBBV�Z��7����nٲ�{�{�ĉ����F��J�S�L��GEE���I�&�t:OO�O>�$((�iӦ~~~۶m���u�ӹs簰�M�6-_���<-[�0`��doo�{��M�6M�>]��թSgΜ9mڴ ++��ׯ߱c�w�}�;v\�z5?幼f͚�ٳg�ʕ�ׯ�D}��]�xq���T��J Ir߾}e&���/77w������...˗/��j�ӦMsuumժ��ŋ�۲�̜9s�ƍcǎ��t���6lpppؿ?7��_n�G�~������O�^XX���q�F.������3f�N�<x��o����������ܹ��t�[�nI$�{�V�Zi4�����֖�M����O+W�ܶm�P(���Y�h�^�x�֬Yӿ��s� �>�L"�̟??,,� � ++3;99mڴ�믿s�H$�<y2c�3f�8x��E� DQԨQ��.]j=�п�ƍ�J�R�;v,�����V���[�nŊ\>p�@n��ӧO/]�4k֬*Z�A��y� ,Xp����K����K�ҁ�3�233� F�tPPP�.]���^�J.D�s��Z���2SRR���Xf䮴�T$�?�٬V���L&��(�Jm� z3�?C8�(���U5�Z-��y�5P��)..���-a;�ɤ�h�r�_�Wvy�L&�^_Œ/��T?+--�]�:��eY�Ο??gΜ[�ni�Z�Db�����+..�J�6���`0��w��p9~���P�R�4m} �t�*��˲����4�5���w� ++ܲ7��+�g���2���^���?C8/z��+Ԭ�$���m�u�A���TX� ++���EW�=��!.?s���U|�"��ಳ�SSS�o��-"��Le �]�� � ++[���� ++�B�u@D3�m�iӦ[�n}��g������5؇B/�E�^9�e�Id��$5nj�PB��a,��`8�B!d�B!�l��B!��M0�B!�� �S!�B6�p ++!�B�&N!�B٤�U��A��!��ܪ��� ��q�w ++!�B�&N!�B��)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6�p ++!�B�&N!�B��)�B!�`8�B!d�WNnڴ)''��}���w��}%�F荗��r���W](..���յ��ٳg�?��k����l��|f�ڵ)))� �|}}{��ݰa��@�Ѭ]��k�����/^ܿvvv�v�F�ՠA�� ++?�����c˖-_F����9s����{���Eg0�Ν;a��2)..^�ti�x�̙S�N�@ ��,s)�:u�nݺ�[Ý;w�L��S���b�;w����t������}�ݢE�����?�r��������@vv�V��f{RXX�{��˗/sG7t�P�@P����n�*))0`@����ߏeٛ7osG(��ի� >>�ҥK��gϞ\be�O���'O��v�������W_}����J���Ԥw*!!�l6��۷cǎ����~��A�V��ŋ��^xx��Y��R�ĉKKKkw�2T*�;����c��4jԨ��D�`��_U�T�`4?��s�JիW/�P(qqq� �ի����[o�u��E�4�a�?u�ڭ�D"9x� ����v������s/�ܹ���X�#S�N]�h���?TgGF�q��� ӦM�ݻwtt�/��R;ǀ��b�,_�|���$I>}����e�����'O�H$�fȐ!���Pe����G��p�5�k���_�f3��&�25��� �������u�����`�(((����H$-[��H$���lZZZrr���]۶m�B!W�F��{���drss+_~LLL�=&N��ݺu�<y���=�������S*�O�<���n֬�����Nw��]�N����%2s��=�BL�5�z����8::.Y��$I�@��?.Y���e�իW����ݻW$q����ݺu㶳��Ο?ɽLNNvtt�����Ry����BBB\\\l�d```VVVaa����Çe2YLL̗_~I�tbbb�H�LMM ++�R�����!!!\�����yyyw��urr���gY��?����iԨ����������{����͛@�^�(���BQPPP�^���8�NעE'''�+������'O�xxx����%&%%%%%����䫟t�P��(*<<|ڴir��<xp�ĉ>��:ϱc�ƌ��;��@~~���h|��y�&װ���)�J����&�2�p�$ɵV��ǠA�N�<��W_���;���,�Ι3gԨQG���/fϞͲ,����7n�������b�2����^����c����������ƍ;t�ШQ��n�ʥ��5�(��'nݺuϞ=� JNN���4o�S�=zt�ȑ�� ++��f/^�ҥ��{۶m����Ŀ}���u�֕J�L��O�6jԈO�y�f߾} ;;���<r�H�>} ++m�$74���uk֬Y%%%iii���b<xpժUQQQ�7o���=x� �V�ٳ�ԩSw��Y�h�����f� ?��ӧO����̙3�;ruu ++��O���t� �H���{��M�4i�ȑ[�l���oG���� ���=z��.L�2e���\�O?�4p��ÇϞ=����|!�V�t���R��]>����rrr�`���:u�@��ϨQ�N�<�m�={v�ȑ��ok�*ž���y<�{��]�o߾��j{��u��i�eM&ӤI�~��g�e���Z-˲�������=bY���?�w��[�n>~��zj�zy���3gμ{�.�k�y��q�r�J```fffe�^�`�ҥK�aYv˖-\0w�ȑ6m�dgg�,[TTԪU����| �y���{��1n;)))00P�Ph������s������������:w��3ft�������h4��cƌ���v�҅��?^^ii)wV�~��<x�l6���%$$���;�6M�4���eYvٲe������\�e˖͚5��^�hт������QQQ\{r���v��qۼ+W�DDDt��q���*��K���_�ݻDz��`�0a²e�*+-)))888==�e٢��F�=z�(11100�ʕ+,�rC�s���ˣF�E�T�j�� e� ++ŠA��N��o߾!C�����U6>.\hԨ�B�P�ա��/^��e_Bd��N�:u���;v����w��٪U���Ĵ�4���]�����͛7�j�gΜ9z�(�����C��9��sww/_����ҥKw��� �~��w��{+44��`۶m ))��]���_~��������]�(�ҥK,�^�x1**�������"�T*7��ܜk����<z����e���d��]��������V([�neY�rrr��� 888??��ՙ��ܝ��"""�<y���f6����۷o��ͬ�,�%��{����*���4l���ݻ]S��EEE\?�cǎǎ�0a-[F����s�B��{��W�^���7n���gee]�v�ѣG���OJJ�}�v�z�:t������������ ++˲6lhҤI�N�ʼ�P(��_����~���� W�����0��~�u�Vǎ����K{%MP�j8sh �f����W�\���qÙ�ϟ�:���_�>��ݻw]QQQ�7���RRR�0�X� ������/]�4u��֭[���pӞ�Z-��(�kn/�o�榹@Ϟ= ##�z�B�W�~}~�'��O�1bĔ)SZ�n=f̘�C�����#7��ڵk7`�����7l��������ƍ�8qb]={��2e�G}ķ�5Ӵi�]�v�lٲG�� $$d�֭=z�����H���S�Hď#6����sqq�4iRTTԼy�>���Ç�� ���*+M�P�T*>1$$���)--��ˋ�D�Лg���'N����.s�k�کS��X�"<<|ʔ)������o�,YRE��������ԩS��W�UȦ��駟v����'�x{{�G}d��AZZڒ%KΜ9�����urr�i:77���������}��vvvyyy���@ݺu��2��X,���#F��ڵ����ׯ���i�Q#��j֬YBB����ִiS�T�M}�֭I��Z�:t�ʕ+w��U�=�"�a�� �G�������ꫯƌ3dȐ6m�t��іz6l�����/^�������_�5""�/c� ��W�x���gϞ]aN��T\\�=+���еk�ŋ��/%%�{t���������k���999��X,/�MG�;y��7�|�{���������5i�����dɒ%K�T���@۶m�Ν��g�U�J���UȦ��"��O>ٱcGBBB� z��jժgϞ�T��W�*�J��.77W�P�ݻ���@ �4i����?~����{��2Ū��#G.^��{���{��1��Z��t�RRRRff�u�ڵk״i� ++wMQԬY�֬Y��ѣ��҇r����;|��իWsrr8�S������СCqqqϞ=۽{��q�������ܹï����SRRccc�/_ޮ]�����Ju���k����Ν+))4M��8m�z������܈�T*�ܹ�����t<{zz>x��k�F��s��K�.������kY猎�6l�ɓ'SSSo���?6����ӧ���.]��o߾Q�F@��u��E�R�ܹ�������̙3,�v�С����������߸�sz3�:u��?~�w�bq|||||�N��w�ޜ9s�Z���wݺu>�T*���N�>ݽ{w���G"��5j���2����^IT![��k߾}�^�V�ZŲ��ŋ���w�ަM�͛7���;&L�ݻ�^� ++ ++�>5eʔ�����<��8(��d�~����d \��}�v~�/��8~���ݻ+���˗SED�]�ȑ#���[o�j�j���\oV�.]f̘��{�u���ɓ'��-B�7n�=۽{�v�� 8�|��3g�X�B�V@FFF߾}��r���͛�]�V ܻw�o߾��D//�͛7�m۶o߾��nXX���������盅�����z����7�L�;w^�jU���7mڴdɒ֭[���?..�:���çN��iӦ>}�����-Z���y:w�\�N�f͚�h�"n�����}��+W����GDD\�pA�V{yymڴi�֭�;w};7�7�^��5k�lٲ%�9�B������ϗ���D��[�^�|�]�v�:u��d�e����̙3?���{|%MP����][t:��d�6����b�TZ~5a�Z-��Xe�d2���:::��ݺu{��w� ƥ���l6�T*'''�Q���`6��Ri͎�7��d2��\_�uXXX�=�KJJ�Ba�ps&^��������$�\^��[qq���?���ٳ~��Ç�Z�D")ӂUVZII�H$����P����1��H:��������������pj�٢����H$eGG� ++c&�LV�/6�2a��� ++۠��2;;;�)D$a,�P��-W��h<v�X�n���Ƀ�EY� A8;;W1���ѱ�u�ppp(߂UV�\.����j`,��=�\�r��L,67>�W���V�i�A�uf6���������� �2�B����C���{�B����z�B!�^7N!�B��)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6��w��Z��\���t���|�zU���M5a�B!��M0�B!�� �S!�B6�p ++!�B�&N!�B��)�B!�`8�B!d�B!�l��B!��M0�B!�� �S!�B6�p ++!��X,���d�^��+�B/W�?��Be�ݻ���G��(�:%//o���111b������LIDAT��eV !�^�����W&�_�~����T%���hժU#F������Œ�����N�4��������#F�(**JOO�?����IIIiii|��������]{�z�^8�jԨ����|���~~~={���گB�53p���M��R��ڵkLL���+�<~�������~��������;wnhh(�8|�p�Bo��Z�n�m?~�Q�F������������@�-�B��ٳ�����x???�R�������5Ĝ������K$���P@����`۶m��������J����G�[���V;dȐ��\�r���������!����ܩ���/����ٳvvv����������y�湻�gee��ƾ����&M����Y�f�j��ɓ'...�ׯ�e���L ���@ii)�x{{;88��7�g�l6�Z�*88xРA�̟?͚5�B�oP;O�EDDPu��-�0��Ǐ�֭��������7lذv�����?{�L��}���~��+:$����Z�B襒�����^^^\`������ղeKooo>˲<������?~�~��{���cܸq'N��j����!���N8%�HF�}��)�x��Z�nժ�VHH7�ǥ$'''''gddPu�ƍ۷o���=|��V��zْ��gΜy���#F\�vm��7n��߽{������̙ӳgϝ;w�ٳ�ɓ'_|�ń ����122�ҥK���!�R��B ={�6l��ٳ���A���ۗ�M�^�/..�K�.����*�����?>���_Z�ոq�����ӓ�锔���X���͛GQT� &M����ըQ�WQk�z�j-� ++����~���ӧ���ZNN�x{{K$��6mN�@�(##c�ڵ�v||<� ��D,/]�4""� �ɓ'?y�dݺu�-+V�ذa�@ xEG���6WE6lغu�Je�����+W����deem�M�6�7���u벳��j���וJe-V!��,[�,����i��:�ŋ{����=����绸�������?=z�صk�+�8B�D��*zxx��d:t���&�iʔ)J�2""⫯��M����7l�0`���aBCC,X��e�z�m۶�[h����Bn#%%�ȑ#'O�<}�t||�իW�u��7n�8u��Ν;Ǐ���ͭ�Bo�e��5{�����gϞ;v��R���7iҤA�i4�\^&�N�3��2���B��Z�h������+33s�������<x�u�� ++�":::??�kah�����֭�ݻw�6m*�*���p� ��߯��O�Sz�>==�СCF�q���|:N 6�f�C�>�z�P($� ++f0c4m_��)�ЫU���v�N���O�0�����?�N�i�|!�&�+����$I�m�пY� ��,��B��;�z�^q��`,�B���\(!�B�_�)�B!�TN���B����`�B!��M* ��� ++!�B�6�=/�`�f+�#�Ћ2�L,� ++��W]�пH���u8�B!���s�B!�l��B!��M0�B!�� �S!�B6�p ++!�B�&��Nm 6[����IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/en_US/image/4.png b/data/ukui-system-monitor/en_US/image/4.png +old mode 100755 +new mode 100644 +index 85b75d8..0f0b51f +--- a/data/ukui-system-monitor/en_US/image/4.png ++++ b/data/ukui-system-monitor/en_US/image/4.png +@@ -1,123 +1,121 @@ + �PNG + +-��� IHDR����������hm^���� pHYs�������+�� �IDATx��}w����{f���]z[� e�"���{�1��b�1����M�IL����`AED:"җޖ���l�wo�9�?���)g�έ{���2s����������}� t��.�,������'��"%P�ϲ�ѽ�w�C�ݰ'���qR~����d�#J�Шr�/�}�t �B� H=�u)���;�ɗ���_�|i�@:�_�(i$Rj��_�|i$��ɗFҠ�_�| �Y>�'BA0�,'\��u�Kb%#-�I|�$��i��-�����4E�)��`.�"��K��H+W�,�e1�cjy��? +-!� +-b _����� +-���D���㟅��r���B�#1-4B�(Z���?�>wg�_Ĩ�t�6�i�C�2 . #���#n0bv����/�2�D���:�ŭ)S����_dL�Tj�DW�YǶ3�����8�����K�Kp����ѵH��ѕH�/�.�t�=���qNA���n=��.S���X$LO��Hx/���!���7�d@��a��˱�G�*,(,5f��b��ϻw�N>��j-,�QX�CLr��pkK�� �bH��߽���g�����%X]��<Q�ǧ{��~�4##�<uZkK�c�/�9d������a#���7_[�z��6�W��Z{��o��mw���]e|[�����c��֧��E�ړ'1�Jz��O+���8nȈ�!�8y�E�%�{G!O���co��֖�v;cb�z�O�9�����W���b������.]p�m?�z<'j���~��#o~��##3�SIu��Vu���M?f��@~a������_iok4d(Ͽ-֟�9NQTsc���3X�]�l�ko�B�(!�����tv���݁�J /������@223��K��_�^��O�<��� '�^tDx��>�ν� +-�%�a.���֬�����w]zյ�|��[����]������YY�5���x��e��'��fJQ4E�-��x�1���<n���ٵmkM�Q�%�PVN��jC|>/c2���z}^�έ[&L�����I5V�W__��x� h$���Y��W��4|�(�h�6�)e|�aL>�����9f��g�D�ٻ���C4C���}���Ǭ^�mKS#˲��r��j��DڢƘqSC=�dff*#�P+�-ݽk����=u��?������t; +-Ƅx�vڬ���!t`Ϯ�|]~����!��g��v ���f,�ꋋ.Yp����k���v�[61�����+����u�dg�����l�̺x�3g��Q̇��f���������4�61ge�`����2��/���X�|�ز�nW���������ښhQc�_n^~vvξ=�u�M�|��T��|M��"#�@�t��������Οf�;vWl������>z����1*��{=�����;;:�6�0����ZS}��g��4w��c�kok��/[\����Ǖ�]_Uyh��ebH[k����&\:�6mX/�l�~�H�2iD +-��jw8>~��W^x����س{����o��7^|����Ǐy�����߯-;o*E�y�={�~��9}��0]7=.@�Ni~!�L�*�������G�T���e�S_W����~�[.jok�ኟ\s�MD��q��w�~����7�ڷ_����-��i3.|�?D_��x�c���[R���1�h�mom��� ���6[����H��g��3�&�酗_{���n�W�ʘL�F�y6[{[�NB��~����Y��+|�̙;���]�4B"���Qa���ɑ���Q�8�?�������d�_���q756�S��g$��h?:���~m�9"������J�N�X���/FL#U��.��,���ڈ#�"�*��4��4Nz�/�b�ݿD*�DI��P�4�HP�D���$��,��HD�������JĪ����^�b�P�L40bh��s�ܕCچ�y�"hI��k�#�(�ޫ�1��7��}� ����q����pN�,�HI �0�;b��ADQ(zi��8�4���wO�7��!��EA"Y&n���o`L#A��o�KANk���k��83������G]�4���J���FW"Ϳ4�i��ѕH�/��D�it%��K�+�����MViDB�?C��ai����it%����ju���~O�2$��ԫZF�jk2[���=I�?�|�#����Uut4[�6Ɣ~u����4�����6#��G��w������k���r��K�E'���Ѻ9��l��#I��������t�ut4 06j ��N8�0h����z��=���H~nk���f1�c"M��Ւ��L��O�}�#����G,3m��c��<�$ο��6JI҈/D;J�Iw|�A��H�4R� �يX��)�~ᙇx������vuHCR��%Mw���f�eǘIX��������x� =��sس����C�"M��VZ�%�OJB)��?u�����~a�È��_���Ȟv#Q�`D��*��wP0������ &�[���O��.AR�a��L�l�4����B��[<��-�L>�Sy�(ʄ<��-��n!d2�% ��s��\����lmt�h�hi�r�����������m����G +-#a +-Q�q���۳������?���d�L��s���d�$��ߴ˕����e��ԙ�I#�e����[�ziUH���[W�x�����SC뿉F��g"�M�뿉F4�}�$ B����тiFu�����v���H5�y������?R �._ꢫ��0��>�����Kk<-D¨S�y�#l�.ߪ���ɱ�����$��==�`t���ZP��&,�cX�� ������F���pE����Qn��~}���b7�2�˂zf��mT�\~Ȳ�؞��vH!�� ��o�W�t�G�z�24��g���7�f�~�s�k���s�Xi��-����/�o�m��Yhl�1F�F�酃^D�mCE����ô�C +-�Y����m� �N��U��I��-�8A�;�|���)��$^~��$˿�8��^Ӌ��qz��LI����a0��͐og��p����kI&��Dm`9tͰ�)%��&��s!��/$�O��� Ϭ&)�d����e����r��i�m���4��Y�=3��N�ˎ�XQ]/at��_b���γRʅ6|�!>ݱx/�;3t�� ��9̘�p���Ln6�����Ћ ���A��(Q��:2��>��`| +-g�:^d'��6��`����-.w$iT�2٪��.��L����sL�輒]���)+���2��lq�2�eG{�d�����nb4g&l;�@T�Z� +-��W��?RJbٿ���6kq&�[�Z���U����|���h�vki� ցL��u�5 �S3���RJ&T�N?�s�,k��c���X +-����s(.��0�]�x�*j=5�YVX HT�w���2"Kbe0`�s��[�-��J��7��k��++-(�_2i�:����&"�G���W�Q����C�T�#n��1 _IϿ$ +-;N���(f@���(g=VW1=3����X�0(E� ��v�b1r,x$�O��M���_�9�K�j��tv���!�Pl���͖���)�f��f722�!=�iENdEn���?����b��K(��]qRs�ip�O���L��;�TE9v��V9.\>�p�i�a�t���U����;��X��b�A���ni���(�D�����㧼,ZM?p^��SK�9b:�H��� @� F��p��5��O ����6���[.���y�:�'w��:َ +-3��L�,�m�t3���UK�Waʲ��9xr�@yovU��ܞ�t�X��qe4 ���Q��d����U���>}�u�B�C�P����G�p���\,w��\�����6Ȗ̙���6�0�Nde�f���eƹv\`�X��P�0f(`hȲ�L����6��<�e�tx���&��k)-��9�8���5Sw�{��aFgpfL�8hrQ�>d��$��1�_ޛs�ao������^9�7�뛋�Q��,v�7��K���5�v/�c�,��K�9��9˂�����;�ǢF���'��B��_�;M��for�������@mmճ4{�4M�_�ǒcg�K�í�nK����5�(��`�����u��:w6�T��s,�v/C +-{Y�A\�נ�����f�ͳ��0�)�Q�S[��1��b�,�a����j`N�����9�-���0��6����L;\R�u�iͷ{�3��ei�2�P�ǔg�Y��p.?�ei��tز��\���p�#�ϖ���7p���ilg4{�ÈBq�Dz,0�m6k�$�(^��_.1if� ��v�� &��O@��)���4�c)��b���3���#��4:|�ؽ��D��Ĺ�����tZ ��o�w5e�m>^���v���˷y���(��vZ�F��v\��uZ����['�P\�����Z}-��ҖXӞ��S���9�/X\����1kս���W�u/��vZ���x5ֺ�`᳛e7*F���ߣ#��@^���EJ-$R��G�X�G�_N#���a����ѹ�F�� tO6��R�B��B,�fW�?��B�4�������B����nѻ)�v�F��\��F�ڍDMC��(>��HCz�c9.M�4���f#����Y�b(�XVL0Rn�0��*5��ؘv��?� pll�r��*�K*�X�=��_���/ #���/mS�}�g6��Ѕ8�ȇ��7bSv��%�|g��W$b���1�h���aC�Q�Ec���"�F��_��i�+��_�,����,IYt}6 zEc,eL�K�L+�A:����Q��V]iD�8���UW!��q�a�E%��Jq$���q�LZ�&]�Ȅ���E!!��0�&J��3!��|������� +-f +-��H>�Ҥ�]�1��2q�����㟙�P������d�)�+�P$O��=�A���1i��BF�e�ƿ���4�x��bZå=b�����4�0�O��KA�;�ރ���zS���.�i��lG����w� 5������4gR��SE�l�3�SLYf$�����3�3��ΰꄅ��p��S� ַ��Έ�;������葦��A�Ksrr�@�ϻ{�N��6b�9��FD�����(�qEu����q�߇サt����x�=�?(�[��٧7�t��o�{�^����!���j���z<�֖�¢4�ڏ�������? ++��;�v�����С^;t`��}{/�=�á�DY�V�9�!���v,܃������}ǫ�;�ۋ{�,.� ��Ng����@�tAaaNn^�[���������o�eK��+�n���V�ض�l����%�_��@�Պ�[֭^i�ZBW�pS^^���{��$'7�dbV-�n��� .�a���Μ��Ng������� +-�WTZ���47�ٞ?�²����7^y� ?�yŵ��0������@Vv����nj����/Y�y�~�8�k��6b��9s�>���jmlh�Q�m��2�hinڶe�#C��N�׳�o���4x��y&� ���w��j��y߯]�o�sF�9��i,�~�v��=��=�gJ3�~�ݻvffe�?������|&]<wͪ��M>oꑪ��ߣ���Ps���͛�Ϙ��_����e�r��~z�}�YY˖|���uR�556|�v�M�ߑ_Px��pNNn[[�%_ϙɰ�#����A��q��{o��c�V��;R5c��a#F���~���K �l pí�����X�������BNg���`��^OQ��Õ_,�x���lvG�57���//??33뻥Ky��^��nw�����G��=���hnn�߿��%_��g�y��ٲq��x}Ųow��a��?z��+�������C�L&�>|�_]q�5������c7�P\R��ѱ�����s����~x�7�nf�J��4{��������j���|����o�ΝI�]����8����J/�ٵs�����B����wT�����z+r��}�[��'j���lv��e߯Y=�-C�q{�Km--����G��45]�B�������)+����f�Ym�D{�����uќ7_��>f�X��v�3g?V-F��_��1�`�g��9 ����p��~z��7���qV�m��e���;n�쓏gϹ���!tۍ���'<�>x��~��9{��������o3v\qq ��55���:''����e��-���{�i��֭�:m��f�Ke#�����ۋ���[��-�ͮ���^�O��9j��/����)7?����*��ܼ���K�b��=;wx�^��1r�h>���J�*�C��4=�t�����˾������/����f��㸊�[��a�1���L����l��?ƅ(�Ú�����9s���ukO��ٿo��y�9.����n�k�����¢�Q献ؾML~��8Ì5 +-���#V��b�:��ɓc�����C� �9{��L�����v�Z�\���������_��Դm��ع�������ť�Q`����'1�iӆ��p���������n�cߞ�GW2&`���>ur��m����#1�ڛo��ƛ{�������mRUyHʶ���2T�Ղ��������w�wt�oۼ�l6�~���O�<Yy`��uk��W�pӍ��~��Wl�qá��(�F�ܼ� e�V�X�rE�^�F�3Z�TUY ����ߦO.�6o���1��a���f3H��`2����q.Wg]mm����$}��C�9�]r��2�����e�,�ukVgffM��Ǔ�^���;~¬9���v�>����ӧ_�������¢���=�O�<��laQ�K.�b���6[^^~I�������ܮΆ�:�1���qN��]^)r���d6�����Q�v��(����+&L��L~AAAa��a�{��SS]-�����;g??���G�̝' �����o�}BY���9ta�XM&oJxx<n�qVv61>M��.�ɢ�>t�:ׯ[;}��邕ngGNJeKϛ6='7�p�!��b�X������G�6bԲ%_M�r�?����2mz�^��m���ү��?!���h2�u���]�N��S�mK^^�ݑ�kGŠ��Ų<����-�����뿟0ir��-�YYC��hjl8q�f֜��JJ�l��3/����SW{Z*s�Ӊ(����D��Yw��/��Ӧ�-�55��7p�`��R_Ww����L���a�v����y���-�6��#��\z��スp�������"�k��s��>y�]�Ǔ��y��WR�o�n��5|Ĩ~��3�����"�q�������t�w�|���/a� +-�f^4��jǶ�;�m��l�����������R�Tt:��`|�֖�m[6�4�o����/_��R��� e#� �s/�ɚ�?|�6�;S/�!�����i:;;�i12�MO�Y,ֹ�/9u�dϞ���Gƭw��^��ə~�����ҥ����^�����������x�ѫ���������gp��$���dB�ď�///o��q��*�4=��Y�f�t�]6���+�-�/ �<uZ٤�lj����9W_S �gYV�^�튜���mŒv�/(|��'��¢�?�+�1��w����RŘL�U��<{��Y��z<V��@����'!���_����!��p�-&����}����0l��~5�Q�������������(jҔ������d��Mg̚�-�@�%�h��-�SD�1�E�:\�j�3~^�b��# ������AL��<Zפu�f���p�eV�qm�鬬,�##\\M���edf��,]��_���+o.:lx���ɝ�LNi��uڤz�����1fRԣG�8����w�5c��"_r�-�ؤ�������.�����ɹ����Z��A� ���cY��o���ȕL�uwtJET]פ����K#j�2�b������t��� �IDAT�4�Pq��R�M��H�)�x�Ψ�9��T��a��n�8|��h>�裄F�t��!�����u��K�iR +-�t�e�{V���B&J��Q��3�|�������\WKѕ�~o�H����K#������T�x&�>^7o�Z��e"�Z�/Pu���ֈ柵��j�R4���>��/1��8/�j�J4�&�#)�_����ם�O���t�^I#qH��!�����O�[�)����_�!���4�R�p�<?:Y�WL�/%�A�W�5�I9��<��H�J�Q�M���k��C�L�N>#�E�����F�KVd��i�Ԥ173�9�[�'Ñ�E��Kk�+���K�F��3( +-�g,M��a����K�%��cI�F�"iF8HS0�0D�.�iҘ;d�_��#�@���b��4�#��2p1,�f�ze����%�>e0����G������%O���#X44���(l)�' C�W�ji +-����f�3�2+�X� +-�:Y���NN�E�@*��`��|���ʍd���ð�It�OW�)���b�H��4��dg!c��P2/��9m�ɯ��/��Ah�9J��`���:��L�����UUUU\\2b�Ȉ�-��H.��jIY&���A�ڢ�}"�u��s�K&��=�Ƽ3��4@|�F�q�������YQ��Z����K,��B�A��̥,���������՜��|m������pͱcV����04775��,-=u������^ҳ'�:a>�Çܿ���~sSSNn.� E����ϟ��'����k�wv��())�Q�.W穚�@�t~A~vN�����ò�K�LL��op�Dgx]���l�)�������G�:mZKs˧�|�f��y�^ڵ�E4����?�߲i#MӃJK/�7_z���%��0[,6���뮷Z�?�[o���Bg��>:bx�a�_�����v�/������jU�� jnjZ����?�h���2`�-ܾeE� �9�b�hl����/ 3+�����s���6�7|���^}�`�kjl,:�Y���+���L�H�B�!`pp�IX(���t(;wT�(.���+������>ű,EQ�?����p�����q_~�Y��}Ǘ�@���r�Æ 1�����[������^V>q����P�_��b��)]�r��S�F�3m� 1H�����b���ֶM?n��λ�V���\s�X�}�q0^�ݲ�s.:l��>ޱu����*'����?+(*�r�4�w�η�ᄈ�b��f������g�X���^}�Μ3��ر�K����;�ח����-�6�t��V���7^?q�xIϞ�}�M�~��]8!����z�e���+h��>rd����S&�h�|�U�~H���#�J$�7 ����� ���֯_�r匙��)��+�}{��I��*|�o0p���?�=�w����O�v�wם�+�(.�X�����\u�u���G�?����&�|���?���_=���P�Q���.�O�����ʢřYY�Чo�#�����76Է��48�tﮝ�S�����w�|����̻`�1�e���d���<Ys<//�j�655��0����>yJd�Ѫ���"�@����>r�㸖��+���0�vG�ݑ�1-����a������)N�a$�j�ԥ��P�mJMJf��|���᧟|❷�\s�u��̡��&Nz����;֧_��72s�ȑ�Ƽ���[�R5aB��f�x����7`��q��}��7��������|���?� B���_|~ɂÆK�95�"��Fy�P�Ύ��ƛ�����t{[��d�cl���o��ٵ���9����;�o{������F��;�HUU��1�E=��*+{��s�������&r��tZm6��f�wt�7668���q�;��a���G�)�|�� ��S�"@Jj���8NNrQh$^����%�.�?A����w�[N�>��g���WU�ޒ�ܲy�%?Y`2��n��۷ 1"#+�����~�:;���m�;��Z�O)ggg_�`���k���6n� �D^CM)��Gv�q��ʳ`)�i�`4�J����qQb"��8��crKS4��|~��Emٴ�/0>��k���kz����'�p����M�F3̗�}���j�X�V"�/1Ƽ�&�)���u�OWUVnް��m��ɕW\y�u͛�}˖��C�m#ocK�q�`ytc*�9i�!J���j��}��?��{~��ӧO���-��C����ݾm���k��I���y�&�ǻo�� e�|�cG�����_4��G~q�����n ������@���j��"���C�攓QJ5ÔY�!t!3+������:;��2ň��Y�@���b��Ό�L^K�uN��ϛ6�b떶�V��Z�����%cƍklhp�\ ���d��b��v��K/���?-�4���e��`��223�N^2��33+������456R5{��sǍ�~����ܼ�����y���t�)��t�RN��!�y�I4�П+�9xK����"6�톛oyࡇ;���7"��&�oߺ�b�6����O(+߶e�ݻ�~���r�������wutt���¥+V^vŕU���y*(���D�0zH�����jR�G�Y��*)���X{�t[kKͱc����|?�[�v�rrs +-�֨<xp�!|:�Ō18��GI�k����|�����]9��6��hUU�x��՞>y�D ���^}�����|�ׯw�\� jin���mok=QS3p�������Y������v7�������NgGDZ�GO�:Uҳ��G�r*�#"&rs��1Dr�I�D������y�����%������|��˖}�͒�#F82e'����K�|m��G�s���������z������.- �~���Æ��u���7�*�G�����0��`��f�1{�g}�a<�|bAQacCCŶm}���է��9s��� ���8p������`s�N������;�v�ܹ{�N��Zҫ0��G��7}:ϛ榦�kײ�@Qq��������ܾ�w߾={�>ƌ/?���qee���gm�~���>eY�f��O��k��k!EQY��e'*-5���q@2��Iz��1���c�x ~x7�|��"K�x�����w�e���̝W:tHKK��k6��x������|����[z�w�ű켋f�:;ϛ:�����V�\���O\q��3f�ܾu�o/���~�Y�^�����/�7���5Ǐ��ҋ��k�?z��<u��^5�T#9d#�ŋ�Y��ǘ���c8��^��b��0)�;��E~x�w��1�}>��;o�@@��,Dz�1&F��1����V+��a!鄖�v�e�8W�A����*х@($�bya�����-\������gn�!TV^��~ew� //o���Õ��������c���~�������Ϙ1뢋>[���.6|�u7���·D33�N��#���'>���#�IC��H�����Ő�&����P4'�t��yU�_7�-�����Ǫ�(�7��Xr/�4-�bD!~|#�������6^����ɤ��1��<}TL�B�E�`7�w�t����jO���˷٬������f�a�I2�{o��c�/�����f�,�U�V���\y*O��,��)�tԍN!�r���5�kFH$����HyB�{��(�(Hބ��ЄbHb��z��J��9\X�T��X�*�u�<�a �.��%�@��"�2�,��.%D� Fr@�����W��sB�H|7^A2��T3 ���~cH@�Ɨ�U[�`e�F�(59�4�e�t�����v�v�9!\ +-�#A,L��� �&��lK���'2�8<�@\����0~|b!��b��1;.�QM^q�U��7�I���M��^���I �b��(JG�iDN���A�F���d����S �$�0$2:p�O���"��_{���3�@R|B�r2�j�vd��2,��w��2V&8���*�pC��FKr� �ͪ`��=!�;��0M�a���`�.Y`��2U't�� 9��[_��b�i�&�.�����:�V$�JJP_C��[Sim���.I�`y�$-���cAwb�Yՠ�>C�!�r`@!'S.\X�ny�����." +-�J�H�*�p,M���m�Z� ��[ +-�3m�V����Z� �����$��k8=��:��R=i�� �bm��J� A:T�I} �E/'yn���2��$�Eu�I�"B8)��2ce�<��O�����xAJ�� +-$iH9�,����(H�R���F�99I�A�Czv�t ��]�ʜ��4դ��Lj)I�P�%�k�AK���ʡ�HVT����!a�CiL���GɢPn���@h�}�����Ґ������k�#�^d˾�[H�Hi*j&J�"�@c��`B�q�!��/�J�{���LK���<a����/b)9y1X�qA� �7aiD��HT����HC�?���X1�!$��o�0DZ1@ 5�t�3��4�@p��u��ԇrCK����F!�e������g��A 6I!�d�O��$��k�_S���;V)F +-��eհD���A�X}*��v-I�NbT�D>��B,��?����-��@����#_��"�������S-�(R�uA7bɯ$o�l�@��Gy�3�'�e"��5�(�� L��4�:�k r���Ͽ��@5�0��5#�#_���LR��$�RҴR^���镮1�r�P9,�NoIY [X�G��{Mr(j�}�!��u*�lh����I�#O-�B��#,mN�+�� +-��Hf���<��i&�p{��B'XvL<1��T,f�"�p,Ȏ�p�Ny?Y��� +-�ݐqE��T��H6�PFD�_U��� �!�}�<`h�9���G�s n�W��-h�|D�#9Q�d�CE<&�u�Ld" �Lʪ��$��Os! ���ʒ'��ix�� +-_!_-$#RE��T"�A �0Lb��D{ +-=�]�2% 4,!;傖���MEn���LD$�@YWɥ���%|A�7���J���^�YN����4��)<x�H�+o��F|����fH�| +-gN����S- +-kUGi(���Ѱ���/�TR���$n/������U�D��u�HC�P�Arvi��"�����G��S,��PIR��H�F���҅S�jv�饸F\M��FjN��?��T"���R����$0]擀VoJ�Gg5d�F|!ʬ�z)C5,5�܌���P9����į�ɤx�Sߨړ�dA�5I��ֺ��C<A�q6Qp�����:�)���A��@˒b*<>����^��C#a]P(D���J�j��h2O�_P+��\�T��aREFR�J���/B�rh�A�W�Ŵ��E�,� ��ӓn���N��Oi����^��䈗�Weq�^�ه�-�KLD V���U�(A�]�$ �1�L3* �� �R�ډ�����Î�����-���`�U��(3��6�e�^Q�lU �wd��d�+�! +-j#y�7� +-RM;���g��)���l_�2�0���M��5�sKu���EW-ǒ,Gx?�d�S13Z/�H�'��:x��*��2��fr)$��1� Q�)/IH����vp��.�`��]��|��Q�t#"�:f�4$�҄%�rXA�L2���p��>��C�%�4��^��!�Ys�IA0���e"hy�Z#�FXS��&��G5rVUt%5��S��be9X8�O�!y�� �������U�����v���{��EqWjn��I7��� ��t�n�C��c��2m��XҦ�9~rmb�,<�Dq�M-���U�����Ng��las4�/F��YFH��'Ս��<��#������C�}-�tX�0���slP�4�s�;8'��{*���4�ሩ3l�D�xFIA �����64�9���OS��Jn��*S��g�y�`(S�t�;�����"�N;��7h�F�)���"�1�����Y]�33#�b͐_!e&ۚ�}[K^�!��hĕ)@x�N���V��H&����@��X�Qn�܌G�:.�hp(Oa6�:]��C/v�;��B�����ף��~/͘���7���#e؊+Ȑ $g$� 42�M�W�� #<�0���A��V�����"%���JQ�/��1q�"K�8�<��%ɹ�=����KO�S�*9#s��̘��z��7�_ qȉ�ZB'�AF�UqB*(D5�_*���Q"T~`��������~�Y$��X|��-)Qf��A,}�G*�E�j�H�VUa�Has6/�H)�'f~8G�q胕���;��n��;�|o���tݸ9�IGv釁����2��mM��� WAa�Yk�ֽ�{������A�k�S͘��O4)E��a�gW�k�' ّ�e�O��)�]���6k�͚QX�O[<R�a��dӍ�g� ��z�����������n+� =�G� �����,�s0,'�^)Q��8+�l�{�~������%@��7�c����Xv��1Z����If����Z=�H���f���Vc�EC~����1�Q�:E2�G�K;�nnM�N�XW��D²C&ԃ�L>D�q�c$�,V�,1��0nм'���b�(ٲ���z���P��N��~�aM�gT�i:�F�P1j2��P�Ѿ�&\���z�j"ut.j�(��_��,\�ό�rE�RL�)���Raݦ���I� +-cA�ܮ|������jXn��Xy������@ $��R]�)I<QG +-�ja�F��6��ₔݡp�����P��Q7�q)�K�<�a��x�V+i���{�b��#)CVU��,�X�P�1�C�.�B҄�Q]��磲�F}$��i�zV�juX���¾��H_��IN��x5<�C�s�x_E$����P#K����ow�`��?,�(|gj^�Bs�.A,1�2��a�!����}���d4'�D��+�2b����1�.�ѱ�j�Y 6С�$�4�'�}�31�X�3�f����� �މ�@ݿ�'dU�d��Jh�#8���!�hr�⋘s64��&���y4�t�+O5���4gSD�B���4�g���o��T������[���%���@���F��Ʀ�x�A?��`���r��=��B�����0���e�[��N���������V������Fe���@�Ƙ��)����;�h`Ot�-\+䀬����u�������+���D��t��Y8>�&�~����>��A��s�|�� K�/��)2` +- ƘAf��/R��p��,���y����,fM�D!��L�?��� N +-�^�b��F��m����y8�2`1S;du�f?�1`�b��&d2!�eC/�����g�l��f� ��f��f]qP-lm{����\����@9>� ���8����UƀM��������7�̥�ڹ&X +-�'���oB/v�YTA[��Q����L�\�e;P���!�(�����1�h�p��N��BQ4DZ�@! +-m�22�<�����|�^*' G�a�">"x�L�:AH�n۳�t/��*�`�̂���~@���0/����2��!� �,�C0�_����X���1��GA42��f���n��B'������L���B`��〥���� �����@���4~���)D������h�(X��>VdC4l*�&�WH� +-`��l6 +->^MQ�g �Q>ݛ�Վ����0@�bJ�"՟�hul�Q�a�}�Rv���_��6<����� +-�zI?hK�@N���V���c�����¤��X/t�X�l�O3����P�~@���r�����? �D7�u��}%�;&F����Y����� �IDAT���*�2H"�������}� ,�w�$gA��)�|#j� �@�ء��Dx��=��U�|�����J�R �T!%��o]��!��_()?�+|%P�#������̭�0օHu�"P��}�/yW6��.GR��_��$��=,�cS�R���шrt�~D�#���3���r���$e9��2A�4伺�N#cVl�{� �8 +-]ƊȌ�C٪��~ӪX�t��]�H�Z[���5B�9�����ɵ�"�,J��$2�K��cA7w3"�` +-�6B��je,��� e`�l��P��*kJI�P4�l��:�F>��y�RJ��J.����/��46*(��x-]X�@���u������3�Dz~��� �hĕL~�b��Ts�)��lH�R^T:�k��9�x�GNG��q���(^�%����p%l6���(,��I_���'z�#��"��\������@5ul(���?$�v�(B������L�cي���'��$�J8'��^Q�Q����J ��e$э�E��{ʖ��l0����L���5S���p���8�j��*�Q���Z 03YdE��g���k���?q��"o�L:�j�D2����� wPӈ����:$D(��9 � C5 �%!b�,��M�s����B���!�T-�@�_��0��!�@�d���""�h��Fϧ��@d�F���iN���}F$)}���1Y�� V�����:�,c�O��u��,�0&Dd�����P amNct���f��ho�Q��? +-.���]ơ���0�06��M��7��'�����̌��'�C$��Ĉ�Խ�Z<��x)����f���M��u����a�J�� +-�64�@�ܮv�&<�g���tpDZ��¯fq����Ft `��Id���2�QD28),���Ֆ����<0�G`���n��^�`*/��C#+������,�> +-�9a�E�r3�-��K!Z��R@s��.����4>��hdf�4g)��0�x)d��S��O!�p���&d��3��G��W����D�/* ���4�@�$h�GՆKM�2�7La�y��ǹ5����Y#s4Z��P��n�0R>�x�w�P������3t<��ji 2t��+*=0�F�G����u.w L��3t�4)02���A�������Ž`�W#�ޔ\4��xm5H5�E�w�VR��Q�_"�AD��! +-yG�WUF�]�N+�Oo�e��G��_bD�<����/�2�U�TF71�p��0 +-/����(�Sr�hfq鱘5c�Rėh)8��XA��1�(|��¢��ՎqDll�z��%A +-���.�P���FĈ�Έ��eo�����{1���8?M�aJ9�\��T�� �q*���I��W�Wz��M��0�D��ݯC�vu3[�Ǹ��<]��`9������DEҦ]�ݠ�I�(��V������@���q����f4c`��s��NcYEr�z#��h&'Sq�f�̒1��<|<�y�Dt��y)t^��L�,Ǩe���H<�c_���i;��!V8� �ף0�Z%�U��0z�3U�hd�-+E��:�Q�$8��]�g��n��鋖�鳸"R>%A����P6����i�y���&ΛI�.d�#�V+�vQjΈ��رՊ?;��)>��.�8�航 �;�g7'��0vNGSj��$Gw��N���Sg���3�e�Z&6H�F��"�T�F�ĕ�X��b�H�<�v��ȥ��#�C�@"�2����1��pY�=�5 +-�bqr�{�7��4q���h8��x�� +-���g�@Y 2�"�F�@�F�t�mB*�����3^I���ʲc�a��M��]�L-E��xO0ŒE�=��~�������>��' ���4E�fd��r��"�x ch��m���)V��,&�9�����q���+�q���d�)C>�b��Oy�cBƆs�!�\K�b�"�is�v�kF!.1H�/?�K�l25�&�2NX'!��q���Q@��N�kN��M� ��s�YR�+M�("�;���7N�%w���,I'������^�4b�A!ՠE��jbo1achC#��6�=�����`���u iN�5���)��f��)��т�*Ě �9�KQ�m� �"=儓}�t�4%���p�dD�D�m�Hߔ���Z�d�Ϲ��[)�6��2��Mҕ�Nࢺ�Ĕ�Έ(�"Ǒ����/&i]�z�; +-m��k �]� {Bq�FM�����eQAID�c܊��aٚPOH��7"���n�H�;%�0�X���h��PQS�O�v�7��T�; +-+>i�� O �7f�P0�n8b�^j�q���f��I�x7�RN�����T�,402I� +-K��� fŚ�,�4��d��"��E>�A�g�0Y�EL\�+�Dy�xQQ5������%;"B�(c��-i����r�7����*q�� +-+C��x�=bл \G�u�T� H� +-9pꑃDsI�`ЪJ� V6(䎔lB�_��H�"���[������M������ձْ߰���[���L&i� �T��ZMJ�E�Jܾ ��H]���2$��g"��G��A��Ƃ�J1B��P��I���k(* >&.+Zq=�/mR"����*/T������H���� #�0S�r8��년@-㫓��4b/ �q �L Z�������0�n�0��U�{��2"�]A�B�R.�gb �k�C$��� /�n�OI<T�MJ��Ȇ��L���H���*�H�C5ǎ����,�!��}�*v4��K� �e��%Bq��|iBP$Q� E�vɒ�ッ��E]��s�����lj���Ί��'N��O���E~(�!T��hy���P35���aC�N��D����Bb�ܚi���)�nWm��Q���%�T6��49U?_��S�~b����m�mO=��5+W)$�u�������������D�T��F�?���>�Vkoo��Ǿ^������ػOI�M�|����sҊ +-JUV�PG�Z7$�$cI��坥�τ�@EMm ��T���?LPj;�D ���7c���l�5�Y)�����Y�I�h�_�g�C)�VWAd�d�!������Ym�g e~_РܿgEBH�4Q�'ηHe���,�� �1D��U[�|����+��B'_y�"����Y�H�"y� r����o���#K��r����~��֖�Q�GO�2�֭Z}����^��K�(�4y����9���6��a�ر}��E��O�y�)S +-������[6n����&�3v,_DScӏ��_0k��U�7�8}ƅ���~\�CcCÌٳ222T�% i/�s����ի�2��0�n����L�2�w�>kV�:ZU�q��^�0̞{��b�x<kW�:Zu�g��̼033�Ϻ�����3f�\�v푪�����.�4��G��O�8��b���Ss��{���RF�CʗM!^)��'Wpdu�R�J�h���k��ƼK�2D�C>f�֭��lv{n^���>�x���?���������W�`|Y٫/�o��=��X�j�/�r�������r���~gڌ��o��� ��&��>�w�<��8u��/�p���˖9��Α�������w��2##�����V�?x�.�y���r���3�l�����ҍ--_�_/����='��e��r��֖֧~��ӧO/]���?|�T:cغy�ᄋc���5�L̜�ʋ/644�����e.���+V̺h��Ց)B�U,�Ҏ�lF>�V��@��KR"02�ɫ�C;���=�\�`��^�������D�8;����cǏ��SOR4�iÏ���Ss���|�Gz�����>�3u��۷�7ӎm�h��غ�?ݽc����srrv����[oͽ����B������W�7n��E��~��_~�t����G��R�?��?�i܄ w�{��f�O���?����v+/�~�����tӭw܁1�ضm���_|���|������?�u���U{{����ڷ�����~���/�LQ�bY�䉓o�QVV6EQ��j��[�S��8�۸aä�γ�l������H�%����1kMʁ�!�V�b�)(�����%,�x���,��|>��b���w�۳g���Ц ?����p�-4M#@��L�X,�w� +-<��_6����X�1�g��K/[p���������߷o܄���K�"����) +-!W]w]n^o��ˮ��t�P�DQ�W;;:~����<����(`^�555ǎ�?�O� +-�%o㬬,�źiÆ�ǎQ5��L�Y"@���n���s���7`�B����+�<z�H���b}v�ݹ�y4M#��]ziKs3�>�ݽ���e��DO�<Ґ�@�(�X(�8Mҹa@�L�(J�V> +-%��Cf���!����]p��_,~�מ�Ͽ���������7[[Z�ʇ2(�4���_�YQ������گ�X�c��¢�܄2�T]]����pd�i��ջw�ѣ�p����/9QS3|�H�áu[���Y������+�D���@�������?��ݷ�6�������t�P,���|e���/z ����c���G����I$�8eJnn����Ǘ�o�~}Ff���b�a�rL ��H�V@QC��(� C�E�-�}��R���Q�P�Cc�,Ke5�]w����o����E�����'�y:+;[LQRR"!I�߀���v�hlh<dHAaш�#�o�ֳW/��rΘ�AFFF��Ӓ���Ԣ��B�;v�M7��;K/���W(D�A��)���o��ފe�>�������0b�Hi�̬,��xܢ��x�����%V��3sѼy_,Z�v�7n���1&a�\����ͮ�80�E +-uH�.R�l�"����]�J/TGz˅�J%%kyLlPN������P�I����ͽx�G�2 6��.����{�s�s�E=z� �a�^����ee�سs� �����ڱc���m2�����;��+䓴47WWW6���x藿���;'�w�����Р4;�;J9�&i�`���0������/������#@&�����ih�X�o݊�Vl�FQԐ��IJ��K.��|��NC}���3�;A༖��5��J�A�C����|� +-���3HI8��$�8/a��R�����Dz�yL(/_V�������8�~�����9��~�w���f��~�x<�`ByycC���� ���*�m_V�q�u������g֭^�a������o�M�)7 ��?����8����H*/��Bw���j��Z���;n��o�V:���/��_���Я�������q�z�fn�喍6���oߺ���~�x�]Vԣ���R��GI� >����ܼs�#���6�QpN��G9�]��P�ׯ�h(���'d�A���hm���V�r�e���x�-�������g�~�/���Kl @��yS�:���YYW]{���[�����h��/�0b��q�Se2�G�:� 6,##��t��0�/&33�����s���y�� ��^(*.&�!�B���o���W_]�n��iӉ5�!U��3fȰa/<����h��+��h�\����]�u�?<�4E����?��p#C3�.|�E������eMvW�'ܵ��rk�Y�)�E�"�X�e[��q��^��1�o1O��e�&b:�g�=�3����ŋ,K�M��*V�Y�����rp$��D�.Ţ��,�y�\�<�dH�ɟ~����o�@I�L�F��o�y������"�r��y~�Y`�R�F��V0����`]YD�?�((�/`�:��|2���M� +-��������a$��E-�r٥ť�_!�A������B4�`��v-�ڠ���\.W�2Y�g堼�_��olj��EUU��h ԚXͫ��M�͊l�p�#��o���������v�`��k8Oo�r���l�4i-���]*��_l"#�� GRI�(����EI���۽�Z��ʦ� ��$wtv�.J�Ԯ�B�'J2Q/�6�~�MZ1Ə�/�r��W���c�������"��L^��F�4���vӖB��� n�M\0_�A��3DHϧ�!�'`��.����������F4�O{��B�IK,3��b�~�g?XZ\����ۿ�;�_�[2����B��N{<�wGAmxƮIf@�1/Zs���_a #�\�y���ޣ-@�w��%'�@�-<7I�^�c��D��2�<�Xѐ��$�N�_#5�����N�=[�Z���d�9|��4�DX�CRa�?��6�����&��� #ȳ���յ�X�ah� u&�[����<�e��d-Fbq��(V���0r.�,�B���q���W�BQ0@�~"B�k��gPa|b��0}�i�,o�rǭi�1�m"df��嶑C�cs:q��&Fp:�*����V��9d>�s �H�����8�B|����C��@!����Q�50Y�7�L/�f�~S�:����z�C�&=�,������o�H�1(�yd͡yZ{:��T��"= n�B i��b� +-01��Kl��u��e�6�s�r���h)������������-V(L=�����z̢�?��@����<lBO;0��A��-r��[у-�������z�����]�>]-�d�v�4x�-z���n��Jkl�� ����3����/�`��������<��ꗵ,�`�@�"B�o%e��گ�"W�R�͢�$�تR�]���j R0־�n<ga Y��Ƅ0�Nn�M_k����z�ф�s��d5����U#z�"f����ʵ�����Q f���w�6�0��X%'�l�s��=��![9�n�˷�U$�.�w8&k�a��Qlg� �����I�<-E�)-&��p�Ϛ�&���>;EHw�6 Q\m�����~�N�bf���r!ܝ���>_bXQ��`���,���E�ͳx�d%��K�����}"��[7L4�Q� r��c�rv�ڐ�A�QX)b�X��"K|�e���"���*qR�9�F��Cj�NT�ftXY���OG���ƚef���J������y��I6�Eź ��Cc�}:G:w�u�r�8�.#�]f���rZ��8��3D#��tKnG!�CS�������0֦��6&�� n���v���Ok7u�1g�ҭ2C�KU()��4��ˎhT$ +-�_6�szvm���Qk��d,g5�Zs[J�X�D���Q�3���Қ��[���N��9�. ++��� IHDR����������_E����� pHYs�������+�� �IDATx��}y|U����Ig_!a $�������""�:"����Ό3��y�y���G���ƀ��+¾$�����Ȟtz���G���Kuuuu�ө��n�{�o�{����8�Πi�� ++����~z,E8�l ++婚�Zs�(Jï����T�V���寗��c/�K(�,D���|$�8� ���G�$C�g���]!��G��^�@�z2�α[C*��<����@`�)������<�$���?�.9re�J��S�E�M&~��N��_�{顤�_�Pܖ�I�7$' ++��C8 ���҅\��J&��a��S�x&|���E�j�Z&�����i���/D���9��A�8����"������]�\�(��IQTO'�T�Z5zwm�$��Ƨ��=�2B���@��l8���1�7�!k2^�&�nĈ@���v�F$L��i��@�u;�O��9��q�~�(��7B�l��l����S.�=��P��W��] ��J� A�J ++�O�:OA�,�����dn�(J�$� �2��c�I���E6x�WB�TH��L�!H�����a��������r�/Hb�#H"�$�kj��U������p��)Q�k�Cw�]찠Br��_EwI�.2�t�ަƽ�g�.��_8��nUi�"�_�ᜓdꌁL2^�S�t���2��'k2|��f�I&#�I&#�m2��5R�L2�p�F�����8���K���R� ++� ++j>��!���>���K��0���� ������N���q�Fmmm|||FFs��������lF檪*E���������[w��9E'N��z�j�V�aÆ�{��J�JII�5k��ɓ����|��|�<���Z,��_=�j�@4�D�R�������,p?y�$��fkkk[�r%K�\�t�w��;v�)S�;VYY��hCC�ԩS)�ڳgϒ%K|��R:c��˗/_����`�� ���[�Z����y����g�q:�/����/��dɒ�����Bf����ږ�����+�K��hV�X�����_gff��dzw���{��w�t��/�ݻw����ϟ��G ++��>u�Ԃ��A�EEECZ�$��_�����a��F�?��^�gni4����ð͛7K�t���tAyy�͛7.\Ƚ�������j���R��0��t:�μ��'�|����h4*Q"��y���ӧ����a�DGG{Lc6�EJNg5�ř3g��T*=�-,,�ׯ� iii%%% ++�"--��ɓ�F�ڻwocc#I�+V�`_�$9�,//��zK`����� + +-K�&n��z��Y"�Fԩ�#|���bdbN�( �~�.���Ɩ>�=gs�Ȁz������)4�q��� #���3����uK��@A5In�I1W"1!F�@�!��*��p�㈏�֧���Mzy �Y�,;#�g)��s�q��C�JK� +-P�*�L��� +-O�C�M�z7֎B EP +-`3pŨ-��B�������`��������D�ذ�'�F`k���(EcU�4>~{oQ^\�_0����1&��6��!�81Ц�*�2��� D���Cd�0��SRl�*5���P�r��L�`L ��[DX:Sx�cJ�~cGO7���C�x�o� +-"���K+b!�Q�����,��裌���!M|��lQ҅"D�7}���e�S�X-;���&�CkW�Ԍɞ��2k��x���z�;�����sÉ"sLR��"n�9��.�<cY�X�6�7e�Q#ۓJV~����!��ĸO� +-1�?m�2�!�翌jXl#~k��� +-�]���(��z>�Ϭ���������6+�>�/R��������mCԐH�y�������_B�� ^9*a�E�9�o�)b����NKY�@c��r湥�μ*F��D�v�U�O��V ��c�OA����9�e����)i�J=|F�֯��RrP5����胻_�uB�o���ٓ�D���r������bl+����l�ep���qG Z`��bf��ua�� �IDAT�v5���<�X<������ o�a}mM�Pm]!i~f6F������JO_���b*�B��P����|�`���/���_���`��O�����d�I�,7oM#I�����iI�0%~7�f-e�=��k��U3(v���Ц-���w����L&3;5���a0p��1�Z�R� ������[_U1��u�wK{9Ao�d�#(v�r.�����v��9<���7oI������g��Օ�O~�Q:��f2ݝ�~�5I�n\����m��b�_���]{v� �ݸr=�H���&�T*�Ʒ�Y���L>������Zt;��i�U�"�m�'L+HT��V���t +-3���I�����BN��� �ڰ5yu�JV�0T�G�g&��f�=L�1�pzyi9 +-���FƵ����t*�����ӡ%�O}1�J���Z:z +-/G�N�f3��=�s3�[�[����7Ă�م����}�\.�������h]��]�l`�8f6�=L��0NJ�)���Z孭�[C7���? ���O�g�Z;ڴ�@ ��������[����O�g;�;5�l��>�6F��|Vs�}�w?����ӟ��|䅗Nc�U�3S3'^<�1^_][]^mhj���w��n���br�a�?-��lA�z���U������B>^x�8����Բ�[��WU����x(��F<m<���ߝ����o�O$�ã_��ku���0:|����E c��9t����g�/~tA�)�ph����ށ�^<��#ck}{������5�5������T�T��ۊ�����dM}��_ܿs����& h�'�Ό�D���D`@1r66�͜�S M�U�U����6=1��^��!\<�0VU�"��ya�����\6{�7��h������t��F��0;WW_�p����--W�_~���ۻ:-��,�9���j�tͺ�ж�k4+�D�f�9moC��ûφ��B<�y40�r���ܠ���9��N�'�?\[Y����� ߙ������Լ���>�u���_}iyi����zv�<��$I�3���h:���ɥ֎�S��F�N͞�������M ����קL������Jl+v��!����+�o��ہ` O���w�=��Zy�PĎCG;�gƘ�N�O��x<hp ��X�\����:��'�˫Ǟ?^�`��ݑ�l6 +-��d.���;:�IgB�Ю�������=]��Sm����L&����e5�<Q�jI�#�2d����`��?irUV;�&��mv t������O����5rU�)��������O~��~1|c�����3���c�;z:��$I]�]�s��p��=�8v�$I����f'gS���c�4����!+�����Z����k��V��O>��d���+�����C(jjmZ�[�����!���*��o��I���Ú��Bz���ܷ��������*�g�ٗ��*B��ú`�����w���w������_�JU��SS��]���{����_.�-�%�*�*��c�*VU�W56U��j�c��\Q�*�c�Z��\���He���q:�^���?����m$VU��3���ɗN"�������p�S���f�x<����H�\6����?���W������O2k+;d��zg&��[;Z�Nutw�|���"�]�4dpF��n9a� +-��ކ�G��6�UD���sӳ�K&�����Q�)���zw������� �ؽoOGO����~a����5�5�����~�^2�L%R�,��F0V�������ؽs~������qL�� ���mVa���K�yY3Ȗ���p(д/}������֧��z�7$�1�S����M�� +-�;{�E�\��ldfb���S�I��:��%�Ȋ��|�|��Ka�����_}12�/���6tim]�``zb���Ƕb�<c���p���--F^��O�ՀJ.n�����p���,}g�\WO�Х���@0�03��l6�����G���|���꣕����>�c�����<v���K_}���l"�Ȥ3c�ߩ�� ��F�v�ti �7:��پg���éՕU��1�� +-�K�W'�3}��(�?Ĝ�8N�X�kO�l\j2 +-�MZ�B5'��J�2�b������n�u�ɲm�n�m467H���D�������1�6E ��u�vqʯ���ə@�����;�pM]�$K�x����,/k8��ZF�B_���LԱp�?���������Cц������������k���� ���ջ����`���z�W�??3��G��G��@sk�+o��OOL?w�����C��������ٓv�9"W`�Bd\5���C��F??�zst4ڷ�bQj&�q�g���|���J�+a�~�������_}OVd���?q�ܕ���wx����G�����m��,ˋs5u5��=�t潟�+���g����S�p��s�|��OV�:~(�Ԑ��g&gO�}I��?�hs}�;�����⣏���������| �5����=;{;ռ:q�ၣ�k�_���L�h^˴�ʥ��*���s&��$���W�`�x�w���_~�wkq&����g������2���ּ�2��`g��8��_�� ��>�P����Tx��Pia&���]=wG�~6�;����p��/ ]��ɯ?�pU��G0�>��+��������U���'�b��^9u��g7�����ۙ�d��n���mln��Tŷ���=�s{�%����������!�NWcO�Ӎ�/Y;b.A8���i��Ϳ�zɲl����Qe'Y�W�lvj������A �-XˆH�"�ri5A�+���ݰ�bw6��?�������d" ����c�L&��ۮ����'BUaIr~Ņ0ƉX��k�G#d�#H<nOVӛZq��uB��7����yY�#� ;�쾿�� f��~�M''�4����_�$�*��n����TqY�/W*{ l�'�5P�λfT�l$�9oG�O�3Y�h��l����v։y��B�<C볦�yi�.3Q��ZE�s�mr��1�BL�,Y���U���_�^�ϖ'�Ñ�2�6 ������-�8��Uj���Y�NK�Ŕ�j�XsD~�0�[ +-�QCL�Y���J��wi��U�e�g'�RJxnO3A�}��S���%��G.SjeuzXl +-!v"E��o�����St<��[2/ ������TL�i,���_��ܮpx��B�UElj��%�(d'P 5*c=xOd�"ʴ�|���%�o�wX�GA�����=�'�n�yB�sfZ+��[�2}�v� 4�|+��(���;r�3C��WB�ܿQ +-��TAх����*���c�9�4*��������F�~Pz4y���ʎG�tt�oy���u���I1�(�u;�wa�h��u1.m�'.w{۰��Tn�h*�_/.[dI���Vf��k0�U����b��%2��#&$\�d���J:�|�~��Lp+��Hx��si�@��N�@Kznk�eCmE�G7녻X��9d�CT�胏�[���e�kP79�w隔5_~�f«�-w�><ub���ph1Č'���d�6�"5����J�6��^��:� +-fʐ��l�j�@a��a�(�����.R�Q���]�.>��{��,��卵�pu�������>�f.}|���g����b��/�^���ƅU@d`�"$yE�����:������%��t���(�{/]���D:�L&s�w���SY���<�k��S ��d�i/w�Zt�36_^"��es5u��gҙ|> +-����| ��F`scc}e������R:��`(���D�1�`r⋇g_�SJF=$[ �5#S�����J�<v�t� I��C8���!Wx5S�f��ܛ;z��u�����gO=��ݙJ��<��߳�6���b��zܯ̋H+��6Y$ܾ9<z�$K�=�'_:e��������,���o�gC7[�����x��|�;�߳�ﳡ��D2R[�J$S��k��j������tgO}bƟOդl�J �H����Dz�fz�<�$���������_���Gk�g�6-,UUW���U�g_P1����c��~�ݝZ1f&�eEnln���^[Ymln���1bO=x��h�:R�+�r�6 ��F����mmݾ9����~��w�����Õ�x,��!1�ϩ���������#��ށ��'���{wt�ċ/��V���쳧�G������Fj�j�� ͝d���ڮ�K,�ρr�� n��~����Å�U�����!����\Nc#%����N�L=����-��u���]��YQ�U����=}�%I�q"�Pe��X"�w������O����|��*��e3Yg�]�+AL�R$�N�445TWG����mvz�����&�?8x��� ��`���\.w�ճH3@�\.��Djj4�,�������ɇ�?����<t�ꋯ����yØ�^���*:�J��Z�!����^~�������w��$���?v�����ŏ/������+��ʤ�W>����v���f&��}�I��] M��hsc�������yo|t|ߑ���������g^ػ[U�+�!���n���<�)O�A���`"7��s�˟^<~�9=�((�w����,+Fk���7V�c`�-���LgO7 439�����W�o�ez]ɨ�~,?��@Bt���i��"@�5������~�+���1��|���F�8@Pu$��u����f�ʧ�~��_������l*�:t�B2 ���-+ʣ�G� �G�}F�eY����V1�b�^]�~`��$IRsk�Vk 4�?@����_���*���Z6N$�$��!��If���� I�j�j�67����# �l�寽��4rs��}�w��������-�m�}�W@�Nv�� ��ܿ���wia���^�bH��$IF���+�u������X����u��+��f�D�D�u�Ɓ��{�ı�G��}s��w��������~I�M%SZI�a�Q�C�!�W�DOK�!ݘ<!G1�t�Q��2���8��T���j�J%�5uuFW�W$I�v�J&�N%S7�\�;o���{�z{TU���'�#���Am�JY�����өt2�T|�v���������w�����_ؽ߲�>�%�ܕ�F'������M#c�)��6��_�?H�(>��#����O/�O�i��y��`�\���T�زO�$K�|^߂�P���儜h|�Y'=r����tu��r ���;|�X>��5�����oi������oK���B����o�]����#�r�\*�J��wn���Յ�U�Fǻz{�e�����νLML���2}*q�x�5�̅Y��M�iM���Μ���Ss 0i�j��3�����n���e�a�������C���则" �H�TSW�����l��M����/7y�o{�� ��ҙ���}UU?��Դ��2r��Ξ�P��,��. +-�����/�����ܹ=r��H lmo{�ͯ#��&&O�9�������?�7����>�2�{6Md�Gad������מf�f_�$���-V��T����;2���������3P�P�J�Foݮ�D�:�}~_{W�Хk�l���)�MOL�~�B���ѡE�����s~<0�gsc���� +-� ]��+����l!h�����X�����/��?{q����}�������m��hS���?!��n���x<�m5��h���O�8�B:��Ğ> ���C�$jv�+���[��f�X{K��Xdj*��tM�Vw�ʁ}�`�D��_�:>r'��!��:۟���G�g_{�ƕ�C��i�it��f3�@0��N[Jܓ�'�oܜz8=r�ڐMv�=��3��EH��6��h����W�j�g&�z��%ɼ���a����C2U㓲`��αt��5���K�Ţ`��[�`8dkS�PU5����d�]X��Ȓ�'�����"��At�V�-薑��REdG�Ʒ,������K��?=���`�9rB��jnY�#���wF;ʲ\]�8����U=�.nb (ǻy�HIp��&@2�58wpS\��iY�\�P8#�d��v�2jHcq^�&ϻ g�"�L��(k�� �1��$pǞ��_1�&X!�|�[-|��艝ٝJ���D��}D� ��b=b)2�����H��a6͒q�Hed��]�kFAVaGi)��3�0���3� s� +-@s�)�I +- ����Z&�og9(e��;;/���D��%ﰱs�9df��ƕ3ɼ���,���{N�=��"�͖�b�89X29~�h<a�0�bzĊ+2�˓bK��_3h�����/ٯ��=�H +-��c�`���h QL��11Q�@���X<!�-m�1"���d�\ xX{� +-�Mjn��3���9�ۄv�ݨx��<\6X%��zD�gb�a��9�+�Q�ڊ���.�J1�Q]�@��.�DGOwQ�@@i�"���P�@��#��03�?� +-r3!����VT����9+ډp���[\h�7����Na"��n$`&����o��HUi?�T�j��iswಒܻC��(�ͣʢ�jɞ#=;���T����^�݃�:�#z"�^I��D�X��X`a�p�BBD���W�V� D�C6�s�9�[����.&P/W����f�����\�g�E���DiΝ]u+�Rnv��'�`�y�֫���ڲM&����s����"d���! @���u$xh5�����¾�Ȃ��������Xű+��}�S����{؉n㛛Q4�T�YD��͒��/�Ԙ����5Yd +-✝,慅g��N���x8������Q�,L�BY����n�� +-��!d?��(��H�b�l�M/�rj�sv����f��9�<�w7[V��>_ � �k�4�)���6r#��gw��~��v��4���AE �������ۓ���Qnr��z�d�Z��(���X_��4��� +-vO������a� +-�n]z4�L������s�F��ea����t�t��4��P(B\v��)Z���/�aa�Ak���E`Z�Y�0l��L{�G��Hn�ck==���Ԫ�� +-i�皜� +-���ʎ��h��/f"�G) m'D��S�3�خY"Nq����H�����֣Tr˝�����bb�a-P�8��Jn��!�P���j� +-�7Et�Q��ͩh�SƖ��G�%�kD���X|=���Lb�_z#:�f�iE��:خ�ټ#�nX��9�� +-;���ny�J�e���g�)��z���.t)����J���:͠��c�\�����l�R��|%�$��.����^ZIxG�X.Y���{|PytSW<�ʊ�����q�y���' ɻ�`+F�Bx�cgu\��+5z+��4�) C��[��g���;t6ov�Iv��E�|}�# +-�r�ʼn�3�b�3���?B���Ln��q +-?ϵ��oC"�yO�x�DZ���KS�5'�p�;#�#������R�,�̈́�>��U +-|�����J�W�t�I����#סP$����q+Zc�_��l��|���Z9��nI�B�rT(s��*!V�B�i;'гU[RE��˙�U�}��+w���'��2{��/@�`XK"���uK~�_y'r~���U=�an>T �1�4,����_�}��8/��h���3:� +-��AwƢ�e��vi�ϬU���&D�ZJg(|�K<O�(B��7�)(s ���^q*NE9�qe[��:֟m� �_6����3���/�z ˖�_t=%��o������ǩ�$�[�d��P�2 Nx.��5��¼�w�� �-:㉍*����s�Sr3A�X�Dݭ{�ۡ�E.��T�b$b�����{��fcw�F�� #��"�P����)pD�G +-F����c�'G3�c���W!*?�*�J�0?w���ݳ���x(ٯ�l�˶�|�g�*C�|�_�HX�Q������ZI>8���cOc�f���o�F/ _)[�S*;)��S9���~D4��XIDATd�u��O��s�B�;dy�)9�|O����|�����Y8 ���b֎)�2�Д���q�(�UJ��lx=���"�g8�7�e�mShW�Uq�I;yP�Y��w�Ef�qhˋg�\�w�a�B��z�nL:�v.,��*]����ǀ&qUC��L�3^.��̡��=�o'��V]a|����I�8��������RE%V�J�ڈ'�����(!��8IfB���Gn�����B�z,��.�R=�QV��_R +-c��C5�pMk��=Y4�c&�q�� ��Q9������- ��27W��? +-�]��o��=�X7�z�C����cl�������^Q~:Ȋ2\��e��_�@Bӱ +-kVxV�}�:Gq)�'��+*������D�o�����۳�B/ܞ-+�):vѿ�����j%�Z�,�������5�U1��1�9R�P��L+ +-�R���%�����<��=���Q�6Z>�u��D�RrC���-}��ݧ�x��+��Һ�)@��v`3�������ɥ'����y�R�_I�D������*y�ɢ�?������S*���-�6���g��g#*���f3Ŕo�L���پ$��f�>P��~b$j��]����L:!�͙_臊�Y��?Fk�F�EΎ�t&� �o��DZ��B5Ց�oW�k�����+c�(���mS�r�Ǣ���kk��lM����VZu�'(eq���\�q,ݾ�.� ��ܳ��u���NB�j�ܣ��\4>+!u%Թ^�o�W�����KXEH-|g�$YU�EM��L.'��@B(��ZY��\����D�>�R����ἄ�<��HVAR}����Zdk9�KnBc,M�Vc$�B8����5�M�j&�[m�XooUA�9����%IΫ�,I*(�T%��RYIR��_��!9��^��R�z�e=��6f�a�A�R0��e��մ$a$�sH�K(��y�Dz��A��|��%��s�p�~j�y�A(��p~�n`��'��yT�dPsZ���$c����W�99���L�y_0+KJ"^_�l�� �%�jR������%�ɀ1H���|8�N��[�Dr��)��V�?��k�'�yA�8�<�����u�i�Ƞ�'��y��8�Y�� �yPd�i�9�)���+�D�P@�i���0HT�H�5��&�� KP��q�EN��oW i�:����%����N��R�+��˲�N�@��PԴM��d �ɺ ×��r�=!ׅ��z�u�B�iV� �d�3R�_�3�Z�r�8A�n��Wp��?�ܢsn��+Kq�Y�����=��-G)����˓j=��A��Q�Wv�1�F_�ODT���*A��y���6+��|1��wvsz��Li�k��ƣ��������� ��Ӷ��بeډ�ܩ�m�W#�3x��K%��[r�� +-c#�w���5G ��:l�!�?x�X5�r����hځ��c)���Z<��s����s/�k�,�IL��C�rCc���R$��?C<�*�,�%-z��,X1a"� ����/�W����yg�*��\�L݊����0�d6Wd��'&���_�.Ὤ���]v�-T6��ͽi�D�#�B>�x"Ȍ��B�$^!��n�7�p�y݅WFlEI0�+���N�����/1�r��0�q)y�b��R�|�V��%K��}�e�Uz�-�%c)��I0V�PFixt�D_n>F�;�*];ij=�ɕ8�} +-��r�¯K�b�*�/R2��r{ܲ�U�2pY�+�⌡���//�K�2���Mi_�>�� ,�o?���yd �R�J�<]���l���Iv�E�]�����M͞�5R�#.�4R.�t�P�4/j��Z��j�M�/������IEND�B`� +\ No newline at end of file ++ ++���3q�D�� ��b@QTyyy���=�������S�L��ӧ���\�tiҤI/^���hnn^�r�A�Ο?/�T"5sĄ7����4n�8�@Qtƌ���h�d��_�544�8����~���~�֭��ws7::��a~�����[,��1�����,�d������Z����h4~���j�:99�5Ԙ��l6'&&2WL&SLL�8dxDkk+�al����:�aÆ]�~}ӦMC�8p`kk�V�e:Ė���������d2�4��ښ�� �T"�˴���}�n߾��B�d[[�B����0`�[[�HOO���R6��k�X�M�AP{v�ŢV�ٟ.\8{�,�|���v������̙3L�C�M�4 ð�����������f����J����$p��ѣG���ٳgϟ?��tnذ��t�_���������w��A�GV�ZUUU��k����mݺu]���T�?[/y~ ++r��o� <��q �0ob���DGG#��v�Z�v��c�\o�K��`��ً��'N����~��={�`6|���z���7�|����s�=�qqq����.���`^��=E,\�i�����X����T*n����l6����$�8��5�ZM&�.s!���2�W��5�$����+z^+@�q�咬�������.�/p{��ge�yF�{w=J<�ٲ����d'�90��G$,]���d!Z��ze\�E�B�@z ��~� �K�I�7�Ca��(^�߉�"m�cר��+,�@% ++Q`����nˌu����@D�V{�$ ���ݣ�ɉ"�(������v�y^[&#��L.�$���ޮ�$� ((H�?��2"C�xK,�d���0�)�����A JI=8P�I2B �g0#dZI�|H ?�#���2wZɽ����-�.e܆���'�e�u�K{��WB�m�2�"B6$�0��s�=d�c��Q�d2���'Y�Y��j2�I&#��L2A�L2ҀG�E��2��¤�mF��!$�`9ws���~U6P���-V����[b���K�ַ�Ҕ\-��T�4z�Ѡ7��;"Y���6S�F�U*վS�cX������zť���۾M��X<�j���-��!�D� -�l!M�X��o�D����?�*�g.��X�����fj2h��ǃ�^V���W�Y�) 2�i35X�&�I=���+c-�6�Z�;]��O�I�s���H��h5�v��kN�Adw�tڻ��H�DZ2�7�0L**��8���^�H"�!��l�r�d���='{�}��֜���w�巬�<@��42�q�����&�u�@:�y�HMf��Z,�]~ϖ��\��SJ�k����Cb��͠3z�ǥ�<2K�]�O�H �A��V@����{I��z�Ao���C�.�W��ŇΓӷ���O&�O+�ȫ�� ++L����+�� 80�ړbso_e��<RP �Q�=�G����G���i���d�݆7>��hH�*I4(�����[qA�V�vp'�_��ϙ��� ��y��z ++�q=t��{��5�~4L��H!Y�-p���"@�0�<�c�#�d���n �֖yY���Q�y�yW������>2�$��bm��$^�/z�w�X�P@��ƅv���. ++� ?w+�[bo)=�_�,pe�!��@Um����>�)�d^�u��@6t6n�����6:e�f�C!�/I�[)2�o�{�+������ބ@�`г����靈{�cW��_��ۈ�����T}���A�&�_KzdFX�O��%1�9����x=le�psJ܃=4}�58�³8�����${ 8<����-&�� ޝ2�!Đ�,���o٭_����r�}�����[�T���ՠz���y'�z������iJ��}"�S�J����.Rڥ>����I{u�.����3���-o!x�l�y���r�~��@p�{����75Ɠ�墨����S���$���ֈt���:~��xy���ŏ�!@����'7aX������c^��=v���S�u�� �p%fP��ے�[���9q`�gO%YH�ug%/�����'�3?.^�դE�@#aTc��#�A&�0���|���'oI��Ƌ������k�ج����h�4�L�.�w���j����:���3j�#��}g����y��.�d��}f����{c���qd8�;�JU�~�K�E����~�.� �WMz���Q��Wo)#���]��Ecݺ���/x���H*���d]����N*�[I,`�X+��t�Q0@��z�Z�U��0�g�n�]�� ++�F:?3��T�M�B87��Z�˜�����i��{B�P�4����_2�"�[cC��6`5���5Y�ƵV4JEI�QXq���\W�ءAG�S"4EH:�j�W� ++�(�M�Pw��F�۠oLH�X�Y$�����b=62�x~�_Tס�1���k�#אf+22��n�B=��.�G����OUڬX�Usӌ����� ++/���y��Cb�5b,�T����N�G+P:=��$��. jh'�Mc Ć�J�ѽo�Ƞ"c�Ȫ]�i��]Ŋ~єQK=�����.��rM&�d*��bi�bq��V ���&���B'���?�����K7�?���)����W@�M5B����ڵ���S��;:}�'*ќR(�G�l`���C���o'h�"�:��gv"���nwE+�B)�5()����ft@�gc��Mlw���B��ɴ2���W[��o��N�;�xq��n�T6�/�M�U�bѾ�l-T�N&�vʤ�u�J��*��.oF���]'I�u�2` ���DQ��fK[eՕ��~�Y��$A��u*��,z�J��݅�ghz\m�X-�O����w��ιɊ4ې�F�P9�6�*���`ő(5��������Ȧ���P)�ь�e9 *[�oG1��U ++:F�@Yr݄��D�����"$ �V�'��9��B՛�ن���VB�b4��f��;{��d�A �p����J���$�^�����[o�b���j���8�_�&&�v!hC�����*E���m��*��뱧��w�%/ա�wL����}�9� ��4M��bC�T*��D�ES&2s >kIRcBjM���8�b�SԦ�-���X���NH>�'S���UE h�h@����$�Aq�Wֶ�z�_���\��EVo�q�$���efK�3��r+��7�He3��� �Ck��mv�Ό���� �hE,�c���Z�Z�N %���f'RX�L@(C�Q�zWyRmB��� *�i�ю4Z�+Z%D�)��A�^I%� ���R��8��� ++����-�$M@Y��� ++���Y��T�f&P:m'���:)�A��" ++��b�=���'�/��J�J���qT�����iFl8jv�̓Z%TT�(mr" ��[H���)%J����4 ++:�H2�|�������9��N��F Z���ިRjt��w�j8p#px& ����z��]��RQ�S�b#0�B�Օn��)����-n�l��j�^J�k#Л�NI$�7�h@nZ�)zA��v<"��kvbM6u_�UHb�$I�P��:���&�*3�H�Oo��F��Ԥ�q�j�Z�Ѧ�>�5�j�Pc�������Λ��68��U�L<��^��v�$���[wuJʊ�����Qݮ�X-�l�ePF��V��{W��,���t�� ++�R{9j����!4yKM@o��Y �)z� �-�R�R�@��Ƭ�x���~�n��09;�^�x��Ѯ�>۩�:�M��z��;��]w��֬�D��ުv���^m��@�o�+o�]��:�ܻ��u4����j�ך5B���'��2��W�J2�@���,\�R��G��[��{��n��3���"���/��.���e�2ɼ � !�W�M��£i@�le�� oa�I�;��,Q�R~=��^���>n���^����9u��u�6��9D)�g���[�X2.�x��$��we&С��Y�Ҹ$�j?����Q59�g'�#.�`d� �A(�=�I��2�� ��뮈W�]mGM S�s�Z�!�j� �(�� 3��B�W!Y��3hڃ��;<�(�2���h5�7�ȯ���uͰ��U������x]2�,��͉����1�� ��%@\b�|W���i�}W�4��ymF�h��S�Y��������]�O� �_�p����D�p�$� !BA���u�[4<�Ҁ�@���� ++x֩���$��!Z�O�u�xAk��"��8���kd��=�d.>���<3�m��G>�b ++{+�sn�Օϸ������iw����g�D��K�� ++^�����n��tڧl^�$�d�xiV�� ޮ����ں��xU�4kx���x��I��WS&nn��$��F��5��2��>q<§��ᒧ�,� ~�2�<���fo�R�ݚ�?���ndr����Z{T�2�\������o�c>_��]'�w�#��� ++H�=�$�k]����������� ++��q���h&�d�B/tF���) �9��t��:�6�<��n�L5WC����S�yL�M`�$C��(���Bx��ߺ{��vDӷ�0ξsnV^�D���g���.\��G/�? �Ƴ��E{Y����L2�$�o �} �]0|�X��0��8U�K��|Nif6��/�pɡG/Z�����`�{xa����g���E�l�g�G�x�� /Zt�-�Y�+>���_�{47 _�,D�������^E�$��u;,���4��� ++y^m �9ל�SP�~�Vi��G廻�`�<?=�)���[�['�3���'aWb ++�D��u�E���<��=�d�8�V�p�_��-����;O������e��ײd�y��:�'3<�,^(���q7@��-�N�s�T�w���B�y�x����ƛ/��G D�,?�|8�m�SD��kf��Ѧ���x��@a�䙷|D+01�}�G�o'���������|C܋��dl>��߷!�^�9��g^����i��d�%�_�����[R�E8b<s�g�a��D2Ɍ\Iy�5��yqs��=��kB�trw�����&0��]���{7�D<�a��+���@�R��O���g�&fD�v�%o.�6�K�=��j�4m2�t:�R��^'I����`0���:��&����� �~���F����j��^��ӧ�Bq�e^�ti�̙\�i5����Vm&ە��z�q��YQQ��֖���;%�,Kee%�`����:����'��~��7n|��l�������?���S�N�m���,�2CTVgϞݷo�C=����\� ++��ۧT*-��ɓ��n��t��={bbb�J�?��`��A�<x�l6��ƚ�f�Ͷt����D&�⢢��oذ����-��{�0a���?$�[��=��c������ۺu+���C��3f�ԩuuu�}�]zz:EQ YYY�f����c�ian<�Iv������cǎM�2���e˖�����V�y��]h�-�������\��Z�v� ���.\ؽ{�رc-ˮ]��Ν;,;���&>>�I<lذiӦ!��|�i~~��9s�������3f�>|8��M_�|����c~��� �xrŊ��$�EQ�$�������Ϛ50��;���Y�x1�a���[�l�4i�^���)�.���Ð����̙3�[E>|������ň#�����ƍ#G�����q|�ԩ�!//���x������쳗.]:s�LRRҔ)S�j5�lvv��z��m�ZSSS̤�p�A�ല;)$ww���4M�;++�����V�~���(���P(Ξ=�������$�ӧ��#N��lq���$������:���I����g͚��h�Gl6s���%..A�������e˖1�Q�zѽz���ޮ�j�Z���e�D� &>|�l6��{�>���������իKJJRRR�{w^z�W���ѣG?�����x��V__����������t:?���۷������u�>���~��ݼy�O>����w���O>�$%%��������y���_ �E����]�`?���Uw��ٶ��E�����\�r�ȑ����{A���Ƹ�8�hmk+**���X�����;{���n���#G�b/..<hK���BE�����;w������_-]�X�j������<@�T�-��{�$����i�P����]2$..~��{�Ι3�ޡ�?��]�v}���������������f�e������;��T����}���8��?�@AA���~���oo۶m�6���w�e�lii�0aBNN/��p����²�2�8�|cc�3��?���%����֖��3jԨ7n����ԝ�*99y�ر����駟pW*����p8jjj ++ ++ ++.\���6lزe˞x���������i�!Yf&��1��@(>>~ժU�W���ok2�N�>�R��Rh����-**:|�0�~�ҥ˗/�?��'�\��2#^l/��ua���{��)/////�1c����榦�����ܹ����f�]�z�}���3g��0,&&&..����:�0�h4����b�[�|9Ӛ�ǏOIIٽ{7����O�������Ot����Ymm��h�|��?��p8Ν;W]]�M3z����ח�9�� �IDAT�������Ԑ$����`����N�����ӧ�������Vk]]�R����c����L����x@�T&&&���&''[�ֆ��,Xp�]w�$NHH:thZZZEE[gn� � gHB���y�ƍ'N4���������;v�ر#77��;�P�::�u>"� ����^���noog��c�������CQTNNάY���S� �YVV�������wc�]�|���m۶����8^\\L�d�^��>k��ݭ��mmm lVN��b�466�����������n�h��m6�bN�3''�j�>|��ٳ�������:#==%%%33s]ׯ_�Z�7n����l6������UWW��۷SS�9���� ��OOO������o�N�A����������q/�={�g����;r��n�h4��|��I�⡇�裏6o�|�ƍ�ӧVWx3Ø���,�ŋ�V�a� �w�^�ɤT*���{�O<�{��?������D����������tiii�=�������5�[ZZN�:5`������qϞ=��;v���0o�����WA��z���>�0,::z����ĥ�~V�6$p�>��'N�^�կ~��/nݺuڴi ���>�����͛��_����˗//--ݹs�s�=�1e||��ɓ����9�yU��w����3�^`^�C=Ĥ1bĈ#�V�Z�f�ytt�ҥKq�(���+V�pɰ���d2����W���?�?���^y������O;E�J%S�R��3gάY������?�F\5��$�Vz��<��Ԟ<y������ӦM{�� ++ ++ ++斔��nݺ���|�w���ҥK�/�[�6�Mt_���?=>�n���(�B��t.�(�J5�e������L~��/B�V3?���(��`� �����^��������]((uuu�����۷��7�ܳg�dw��}i��t5��C��O����INAl!;�EQ�!HJJ�{������>�`ٲeqqq�g�� 8sBAӴ�<�]A�a�G��/v�U�}��ڵk����-[Ԃ�v���R�U�0vwTPŞ5��2|������G���x� +*��쮚Bx�]��m�i���AB}&�nL�P��yR+� ��#d�y@8P�#����n�4��#�G2���.�D4|;����$Y�ta4�~Z��v�%p "����% /Ӎ�jA��F�qw��Lf�d�Ɔ��N�M`笘���qݥ��C$ɞ��z/,FZQ�/�����zO܍��\�7G��X!�O#��@s��=�bt!�B���`O$Y�|Ae��OZ��#�d]�� ++�݃KRP 9D�z2��Y0X+���ފ�S��T�T+�Bl;�M��)�� Dd�\b���G�,LнF"rHTu�� ++�R) ɭr s���!Y8#4j&��<���$��-4�D$d�� tɶ�I� ����B���/�,.v��d�p ���I(�i�����I&��L`)��2DN���o4��^�,�\��9������,�_'� 7J��`�7J�V)�dB�oD �hoow:�Ldk8���ք��(Z�� d���TWW7x�����$�mjW�\�t�� qg�gs����5L&���8�_�v�d2��ݛ���D�x>�$�����<HQԘ1c�{���dѹE�;v��I&��ܹs����˷o߮R�t:ݒ%K�ZmnnnFFFRRR{{�ƍ� ������k�Xbbb,��j]�tiBB�Cqq�������6n�H�4A>�����"h�>z��ɓ'1c���߲e�DGG���3fڴiuuu۷oOOO�i���>++k����J�W��I��?��ԩS�>�h�^�8��K/mܸQtn�¿����cǎ�Z�J��|�ᇕ���Q4M�۷o֬Y���_�u~~��I��[8�oݺ5))��暝�����g����3��������ӧ�ڵ+##c�ܹ]����_x��"F�g�}V��~�����iii�}�݀fΜ� 7�3�<��c̉$�7o�<y�^�g�,�Y��$I�999�/~��g`ɒ%---MMMgΜ7n\TT�<x����p��y��F�M��.^�h0fΜ��:��F�1G�1�ӦM��8������499� ���QZZʒ��������`���y��Y�d4M�ڵ��t2'Hp��q�f���$�I��.A���555Lk3���p�(�����Q߫W�^n'�0Ǎ�u"��$�a�{�>|��#�<ҷo_E��⚚�֮]��ơ7���j͚53f�x�w�����ԩSG��lٲ���~�����ly�ƍ(�~���.]bB�^�~��/����/�>|%���ޮ�8�H�әL&���dR�TL�R�^����\?{����0\�+??�ܹs�N$9��XRR2h� ��ݻwQQQFFFYY��je�bJa�)�9�D�R�4���n'�������+|<!p������o�����y�^~�e洛������ӧO��S�4ͩS�(��������0a��O>�dNN��͛?�������|&7�$7o}��͛7���m߾]�`A����d.�@���E��r:�.DQ�ĉl��������OOO���èI6����� ++�ƍ���5 ��t@�V�>����ʕ+�S8�.]�bŊ�:�$����O6lذ�۷?���ϟ�Ǿ����0a�8qb���f�������@�V�5 ++�&O�l2�6lذi�&����brKMMeT}zzzff�s�D0��Q7��{���h�q��S���Θ�0jԨA��{ァN�bO�cN$IMM7n\]]��baO$����hѢ^xaʔ)��;�d�`�6��F��=��9g�ۉ$}���}"�D�Ѣ��z�ݻwϙ3��ޫ�����KKK���L�2dȐS�N���3� ����mѢEeeẻle.�� �ˑ�����x�ƍ��֊���C��8~��A�����t��9�٣03t�С�{�f����I����������W@mmmee%A���Ȉ���q<''�f��������̜Hr�� ��ƜH���$~Bbg,���j��9sv��q���1c��t�o������Ç�u�]���ׯ_衇�� 6lذaÈ#pw9��A���<��h��B ���z��ٳ7l�@Q��wߝ��\WWw������ϝ;w���999� 3f�˳ӧO_�~��k���������9���G����������������@ss��ӧ���>{�쯾����{��1'�|��̉$ӦMc]�ns"ɔ)S<�H�D��ȑ#/��¢E��M�F������P(���m۶M�4 ðq��}���$I2ʙ��P]]�t�,***~���A�mڴ�b�<��Á�-N��ÇgeeQ���III/��2����?�p8�A��������~���@�~�؋�s�9ٙ�8r���Ç;�N6�����k�2��1";;��:N$�={��ng ���������Z�{�'M���o�_���o�����[��`0@�!��F��T*����w�w�w�}����J����ϵ!�J�������:����;�pX���0�;T�|� �_nƉ_VV�r" ��.�pKq�-:�#�@�����Q�G������(nӬY������/����KJJ=%'m�u��D���Z���V<A�Vu�s��q�@���� ��KB�.�#�%�AX,�A$dA��;�s??"$�@B� �.}���1 ����R���K��$�t�$��p�"��Ax�-҅���b�^����Id�E0�+f%��]�:D�L��˖r�Bपp��ɘioq�!8�$H��B���{nw�W��Öa �U�ޱ�-a��w�� �:�������?�$�W.��JK/6M(y&��<��/���q���\H��L&�H����T��{P*��� ����v��IR5n&3�I� "�.� �I� ++<~����1�$/.��pE�7�V(�L2)�!�pz����B�)zM%y��œ,x� ++���)6�;���h���$Y?�IeMDH�Wt�.�L�.@88�X��h�d&s��jr:%^��ZU&䩰Zh.�a>��Ri�:�^%J(ׂ\��d5�K�L��V�T$�a^i��57߈����?��\8-�d5�K�S��q�$��F����Eh�] �j�W�~�\�q!rt�nim35 �%0<�*j��3�0O��a��9`Lk[���.�,��%�M��I+J�B��-�H�K���L�i��]:���l���] �U�PI>���X�1 7neJ�d�]��M`�ʎ2x�$���0�pG`ʞH2q���B�4�͖V���;]W�_߽�/>�]$�{��� ��M��;�4?Dk�n3;+9�JIxD`Sdү���z�Ao��'SBQ��A���G�u�T3����z���!�d�@3��`��,�E�2!4�L�.F�� ++!��@&���#BHav�u ���2�Ͼ5B4Y��$H�K�6� � [���~�LBGDzѳ������aa��5J���1b!tgУ_���߯��@0 n��� ++�Eum��҅C6���P[�v��$�鰓��U'e����n$jq�H��(�h��a���)��rB)��}�I�mxS~��q�FZpʉ"�Ne'��4ES ++L��U�0�����FYH��)'�`��SiN;@T���~㺽⦣J�(�����iځ8� iEP�r@�S�*������p'�p�6���T��^ ++���N�8�`���i1E(`*T� ++D�@�(�v�������� oj#�0D��1��xUJ����^�L�YI�Q�PM�"�NY��*Jk#-�T�APm#(�Ӷ�M딽Lx ESZL�Au��JjÛ�����f�a �Q�� �1F�`�LvҊS�V��5��L��C�@ �n��V¬DU�OY���ځf�4��P$E��}�(@bp(��T��k�+4�Fe� o��`���� ��3�C��e$Mh1=��F�ZT�РB�N�� �4IS4M�0���� ZL�d8� ��4@�1����4�@�E�Q��+Qu��ᆽ�l�aiE�Q ++HP�P�*�r�@�Q���!4��R4��� �U9H��@Tʎ�(���@���Q����jDm%�4P4PJDM���v��JDM��(�R J;m%��%I�*T�B� ++PSi��kI3 ���A��4(�� ++P�@� N�i'Zp�AФ�88Q@��َ��I�P�iEL�( ��H�R�j��%�"��hA�Qb�B�(��Fi0=���V~k���DS�$+�N�{�����>��%*C7 �P����ЯߏH�4-�g:c=H���� D���_F�!���[/>� ��� p�B��.7h���>Qo�F���ޕ.����:�|s�����2!��~�m(!�&�(|~���?(po�����Y�,���y�G�5���O��A�������x��L��G�)9Ȇ�4��GA�P��izL k2 T*��w_��#<��Q�[� ��N�R�;]g��.{��_F�"�=���>��vA<5_����dÿ[�K:q����S�4���I&�d�e&Utf�dҠ��B��d�!�<AqR!�LJ<ӹ�A&���F:&4E��JA�&���w9�h�$.���_d����G���3���'���|m7��3K��/#�I2�J��iE tw;=p�$����y�$�Am�[�EF8������d�M2��_TZ �42�m�j�V!�d�/���{`��20A{{3�I�`%��$IR�Rit�^�Y ��h���jZQ%\�k���h��� � G@I����`�C�n�@AM��1DC��B��I��(��:v( ����v�!H� Q�K��Q��VՑ7=�81DE��`�P �Z5�U�8PD�ױ�@5�8�(;�R�߮D58�u���@�$���j�mMJ��B����ϼ{����E��{n��d�C"�a�����X��X��U<1;�������< �E@���{[.+/����h���I��� q��q��_�ο�H�`��]�Vx�T���=�d���0��~{Ez,�����h�1O�%!"�T/[�^��.T�>������L� >'d�'զHqe�5��@�0������6-��]�=#���?��1&=�/��(��@��a��3n�|�jKw�h�2�?��d.p��ϳ<��oG��H◎4?�rE��ЃHT;�K��=�d2D�[o�z4ɤ��"^ph�H�pc���o,F`b���poc����$�D%��d��P�w@xс�^ȳ����Oye������d\�Бd��V��P3�#�eM&�X��^��P���d]��_�7��mZ9Lx�.�gM� EQ��/���w���6���������I�m*VB)�g��̎�e�x�d$I2���3�!]��6���oү��&�.����E�l�.opq�;�?%/Z��6NW���wH������^��@4��Z�"�.=�˻�n A˯{&�[�=��X���L&�AD���J~@`a�s�~5o�Y$d�Mϴ��5����7�S��L��*D��˃2�nA�����L`�QMZ�-�,XF��I.�L�RM��v�Qx�<y�O���y���b��$�H!C�4���<SR�y���߽���lv����/...�����)''GtqQ^^�c�oU-((x��n�^��?���?��p_�l�{���A��rrrX ++���RZ��b�_9�'�իW8�w�^��n/,,��l�ҟ?~�ڵ��������B�i���W�^��R�?��?˗/w��i����k�]�v-t�v��P�&3����ԩSu:��-��|��A��2q��>}���Ԝ9s����T���Ԫ��iӦ@[[[^^�رc�F#�:t(#####����G����gee�7�ɶ���ƍ����ݻ7�Ħ��3g�dee��� ++EQǙ�/_�������t�=��$y��Q�(((hll?~�N��q�Ɖ' ++�ĉccc���92t�І��.ddd`v�w2������ʦN�*�a�C*�oP�u@6�ܹs`���.��.\��'�lڴi��gϞݷo߶m�(�z���[w�ڵ5k�����@NN��/���?@cc�o~���Z�W�\��+��ٳg��կ�� ++� ++G�}��W��_�[���ɓl�8��Y�f���,|�O�Ӟ={�`ǎ+V�8r��G}�bŊ���w�}�����w�y����ȑ#�-ڰa�����G9�<�Ûo���[o=��S6l(..~������>��ohZ?�ޜy���&#Ir�����_z�!�����/������?P}��7�}�ݯ��J�P�[������`2�0����ӧω'4ͩS�y䑼�<�R9f̘�>��ҥK۶m�ӧOaa�ҥKw��1o�<�hiiY�`�s�=� �ƍ��~�����M�6i�Z!_|�E�Z��][[���`ǎ&L��?�AQTMMMZZ�{キ|�����#G�4�Lo����ٳ_{�5�$_��7�xc�֭ ++��JJJ�oߞ������駟8p`����ĉ/��B mn>�$�z2�$|��A����g��fs^^^BB��ݻw�܉aXaa���0***;;;//�������K��>}�$�����#Gj4�C�M�<�O�>����5z��Ç��/_���Glٲe���o��vRR����Ǐ��� Ǝ{���u��566������������/^��-\���������;s����d��ի״i��x��)���� �J4P� ������/]��\ill�i�ܹs;v�رcǵk�F����� ��� ++�N�ҥKm6��˗ ++ ++��.�������f�����ձ?Y���o�[TTTnn�G }�ѕ�ׯ�{��+W�����?�W_}�r�������H�����T*�l�\�t���277o�w��� �IDAT��;�����MK��=z�3>��3�g�>}�J� y�n2�t ��w�}��_�"&&fذa�������0a���ߟ��p�ڵ�C�z`�ʕ|饗f͚5b��Gd�̙ӧO��O���iӦ1A�����T�!�G��1b��?������Y�i��k֬���e�V(�>���|�ĉ���'N�>}����H�<q�DYY�6�W�^۶mcTq�l�b4��K�,�����믫��>�����r���'�|r�ԩw�}�[o�E�_��8�ꫯ9r���M��#�aXBB��>}���233s�С��nQQ�ŋ?���'�v�͛�i�&��>y�d�ĈlHC����+V�?����ӧ?���S�LY�v-��O�:5++kժUK�,��l��?���������� �;v,�E�N���k�����s��ݴi�_�����l~^}�ժ��/���/� �HMM}�����_~��/��RJJJBB�#�<�~��������F�y��ǟzꩌ��?����r�={6A&L���~�$qa5�yO��q���1))�=Ω�7o���sM�$Y__�����7�x[OFQT]]]\\#s���Y�R&Mkk+�a�O�hhhx���y睉'�,$ߢ'�.��[b� s<t�$�O���X,/^ܴi�������-ZZ!����M8ɺ���$��\�xq͚5&������$鞂������Z�_�5���>�3�HD�}&.P����@H������t������ˉ�7��z> ++�8��+�d"��N��82yCϲɤ ++�ٓ!��zɄC柄�Ae�݆L,��o��Z�/C4��P�b�u�d=,T��6����e��;3x�>��Bh*k2��9&Z�k*k�PC`|�H���B ++��t���E�5�H�h �!��= k2���$�E'l!$z��T�9�t��xc)ak�@kD�)��(U��S����1*3n�0�gY�ԧ�����A8\�C�F��V'e��/��.��>��SA`�2q��$c) oC<K}����O��e]1q�{��A_��QW�ߞq�i����m��e� �l���v��L&S[���]c�655QQQQXXXXXXYY��V����~�m���ݥ�J_���������4��o~��������P(bbbƌ���!N�����}�����=���8�~�z�V�ZŽ��G��/^ܿ�C����'%%�L����?Æ ������5�ͱ��f��j���W�bvd@qqqfffP�I��q�1V�y��$ᠫ�LT�W����F��q������ҥK $Niii=���.�q�����6&��mAĊ+]�8�oݺ5))��Ȟ�����~�����ٳg�EQ���3f��������������xi��]6��v�J-�ҹ��,11q �'O^�xqrr�ٳg��---�O�>w��F�q�ҥK'N�`7u�4}�ʕcǎ1�Z�� �JEDuu5w?pcc�+W��[[[���Ο?�n�r�o� � ++��cVVV^�|���v���"����K2��w���t:�͛�b~�8n��ذ4������:������/��p��W_}�mFI R�1cI�P�B��)j/�^Н4De�',�7�G�(��EEE[�nMNNnll���]�r�N�kiiٰaC{{{tt����-Z4x�� 6ܼy3::���3f̘0aBKK��͛��7o�����L��~��f� :�����o�e2?t�Я�k��,��w��u����[�|3�v�2�����K�.U�T�p��Y��a00c���;w�n���zִ())az��������:�(�B�UA��p����g�z�,=�n2���ʮ\��gϞ���#F�������{������+�(��'N��Ν;Q]�f��իW�\���y�ر���_|�g��?~NNw3|�p��������t���1��رcڴiO>���/��T*���rrr0���mnn�q�U����3�<���F)f�>�8�΅�(z��q6�aÞx�'�x"==}Æ Y����w�ygmm�g�}VUU%yDj2�i�����'�0ݵ, ++A��A�EN~�fo��d.VUU}��78�k4����ggg[�VEϝ;�:������p���Ϟ=� �����W�\���ehd�Zq���g�]�����ׯߕ+WF�YRRBQ�СC+++�̙�bZ���g����P����v��j�駟�x� �n\\�(����Ė���Q�L��;F�ń~�j�Lb�>��S��b�X�J%c����>��s�Ν۾}��3F�%aD�,~����V�0S�T:��m�f�����aÆ=���8q�Dzz:�0�� ++5� HBBB{{;M�.۵��f�ׯ_?6^�#F���t<X��1�_�r�8S�U�3�}"K��gϞ:u�'��q��ѣw�uW~~~TTTVVVCCCuu��Y������ZPPp���������f��������3g�0j�~�������3����@I�$Y�eu����L_߆b�0�n�I�9��I�Ξ=��?,^��y���bb"��$I����!0t:ݢE��Yq�gee�ٳ����������d>g��[�h���AҀ222��߿w�^A����Ç���>}���~��"��������tiiiL������3g�M���������9s或M�E�*2t�����]e��u�x�l���%�Z}�}�}��w������KMMݱc�ܹs CIIɀ�F�w�q�����Ĥ��K�.���w �6m������2�L7o�=z�K�C�=p�����7�������s��9s��������GEE��u�b���L}]�h�z��t"Y�l������h��XW�]��d2������w�}��{��fs�8���$e*`��V5j��ӧ��۷jժŋ��w}�M�111���F�q���Alݺ�����������̹s��߿](��1 d�0|��.�5�itA-Z�cǎ���L�111A%Y�s�Bt-�N`�R�(++���tٜ�a�R���0L���v�� ;���piA�t[[[�^���s��nl�c��g�m�Q��Kq�&�o�LO�d����X�?�S��"d$sO ��K�'�{�\�ɋ�1B��ǽ�^��h���-!�*�e��F��Mh������E��p~1.�BQ%Qc�2��6�_aN%y����O�{\�ݍ��}ݨz�覊!�bKk���[j2��vu�L8�|��d���"jw��mT���R"��w���F2��>�v��բ��CK�ЖV��b���C��ci]��p��0�}�5������w������Z�� ��叐������FIJf������m��s�\^��.��B��-��z���Pt�q�ĉ#G���F�����MMM��i����3��않� ++fWt�$I��wy������ ns]�r%��.EN[-�];�'%M�w�������8�<x���������iӦ1王Ƶk��v�ǃ��ZPw��8z��ɓ'1<x0s$7ǿ��놆��ƏϴCnn.Ӷ�����].]����]$��d���N:Ea�bX�$(8KavE^�����ܹs#F�7n\ss�-[ĕ΅;?x��{��Gkk�c�V�\��sϕ��VVV��Μ9c�X~�߬^�����7n�`o�e��}�K�,Y�reTTTAAs��wɐ����ҥK��ki!������0lh<����M�O����l%;v�ԩS`���V���E�tQQQssszz:s$���(++2dHuuummmFF���AEEEmmmRR�G�7t�~���4%%�Q�%%%���`�S( ++�"==�����qC��;�#���]VUU���k��+W��;55u�������߿��UI2f, ��0� ++����x||�9���A��X\\|�w2�-�t:��I�ܸqc]]��h�駟�ᄏ��e�֭iii�������<�������?u�TBB��l���\�ïI'�齥p1�]�s҉q��L&v��^�g��0HII9z�hmm���z�*�D��w�=������b�}�v��ه�/xF(�����_I�E÷[��z�/�Sn��ϧ(�>غu+���������?���O?=o��\��Έ�v�ڗ^z�h42�***N�<9w��U�V����!��U�9p���9�<20w9i�YO�9�3�F�5t��m۶�>}:11�]<�t:y���.��ﲤ���+��f�euu�_� ���睱 �;��z�v��Y��];���@FGs��ݻ�3�<3eʔ���O?�����4M����?�b�0�)�LJ��(�a111&������R�V;r�H�� ++���*��g#D.c��a4�`>f��;TBQt���/����ŋI�d�U��ѣ ��_��ԩS����f�ej�>�ƍ����Z�uuuJ��y*55u���Ç߾};����y��HMFr�CQ@���vO�R����{nذa999������---�Ν;w���1s�9��L&�N�s1ń|��!`��� X%�ö!�����ׯ_omm������Μ���f��.\�@��ŋ�����L���C����2����tZ,���������8�^��(�����b��q������.�� �ۊ~Dȉz�;�P�w`�r����8︃+M]]]RR�`6|����ϛL&��|�ᇹ�2�t�M���ѥ��A0�Hx� 9��-��]L7��0{�� 6Pu�=�$''��՝>}z���J����ûv�2/X�Â�ﲠ�����e�%χ�����~� ������~i��n��4�e�Vg�}���m�?>���ξ�������[�l��;233I�<y�^�OII7nܖ-[~���!C��L���:�7d���7++�������gl������dI�e�bJgF���lĈ���E1�����֮]�������l6n��˗�{�wɠ������}ߥ^�}>�Wyt����i��@�w��i%�����L�X�3g������� ))iѢE*�j����f�:x��{Q6l؈#XI\�Ą��ٳg�߿��� ...--��tv-?���%��a�-��V^������}�%����|�V���͢*(P^-�Z����6�9︃g��f��4�����i�����H��X,�t#8n��^�L���}�$וÝ�D\�b��� W�e�%��+4�w�f��5���d�`���$s7�E��9�����g���;�.8�5�cu� �H��h��.-sy �0�͎��-�3����Ľ٘$�4�T�6�Bo���*��̏��n�[�����4��ܻˠR��ЋEg����.�<j2!�e�[ ++a�<k�����дG�1��L��������vEA����!ؔ���o�����{_U�����5�N$d��DvD�Q���È��3*�Wg�Ǒ;��w�qF�qt�F\��"����{���O�����g��ӧ;�><�O�:������S�����R���g=����#�c�6�&d��J� ++��8ti��s!� ++�M��Ғ�te2�v[c��2��`儣�>�R���_D�x��*Z)���r�p�jDK�Xp( �3�:�Ʌ7��v��^r�7"��)&]S �$�.b"�>�j8(�0131�HNNv�L�v@�,~6,��SNJZ]RLa�/� -��'�8�����!(�0F�0 ++�W3�/>�W<v[�5LW /�S����Gd��C�qeϤ���B�` DdWϺ:�h���,k�}q�,~�3���g�:�q��lH �9�fD�y�����G�ʟ�#�xo�VXHy� U�8��eH� ++{8Mrb���'e"�,x|�3�P��Td��E��52q;�$�h��XU{I�x�����h2P>�"��!�!�#R- ��Y���VeM�= ++ ��h�gY���R��Ȁ0�$&ao�]�*Xʀ�bn�jB7%}5c�P�������G�1��ls�^����k���E��`)�s��@$��h;�G A^��Ш>��h�XҬ���)�C>+' �H2���.9:�LF�^o�8�1g�A`���鯠�����)\Q|��]����ion�MMI���|$��e�N ��4�gȈ�������[��H�FP��Ŀ� ����OW(�* �π0��b(�e���?Wr�����g�`0���۩��(@����h��/#���ڼ&�DB�l���!(���+�_K���� 4f����S�1�'������Q�$l2Q���K� "�Ng�ѐ\#�%�g�_g~�֍�d���~P>w�$CT����V�Ԯ�3�����d ++�LJ�IC�VXpE�z�n�� 3����jO�|� ���7I����̀a�$�B�̮��6��Ǒa-}�����a�s��\�B�F�G��e�R�S�;B8�Eg�'�Cҷ"���!�)���E`z��i��`�I ++��E,�JG,Cd��#�_"o�G.;5iʐ@��G��|k��A��FG����(u��k��b��$"�*cɇ��$W);E �?� g̩3�dV����u��l�,��j�04n��,E��b#�P~@>�DY���Vv��p$�����"}�$�-�(��-�.�e=�ma ++��eR� ++���ݥ�^!�u��z-�5�Ho�� @��_�������c�����YSmM҇;�5�����S_� 0���0VHB�Q^»���V�%M)ϊ���"0��;Uc!�T�����L[�G�~�Y߯S:�0�LiTY ����z�u1xM�}�4c�ਙb~��K? �$���������yU����s|�A�ݐ~Y^�lB�X���W �/̤�l��5�h4����<TV_��'�b�����r �$�E[���{d�w��m<��|r��ޟ {�kE3��$�ɺ�I��A�H�,�WR毖�{��º����-vU!!A� ^��n�@�!�`"���)�$�2��B@B�j�I�����P���_� ��w��J�d>z�����zSψ�w"Y�D ++�C���cb}D-d��Sd��.���s�Cj"4��2 ++�J�蓐 �X��!0�yaʽ1XB:�dHfݭ�y��Â��ݵ>�_P��O��te�)�Pw�L,��)MD��^쇘F\���#�N�y��^ԙ�� % �JQr ++CR��K���!�L��j!!�"�~7�49�n��T���ab=�zc@��O��a�� "D��X_B���DWb!)K�@��z��R�8 zF䣕�d��j��l��w���9.W�-�,�]�|���K�>� d,)1�&�VBv�aB6�ut�Y������dlP��,]���-�pӕ ++����ח��I���!���z��Hi��)�)���y��Hu\L8��b��m��TYM��ȍ.�X�VK�Ւ:([i18�C�[g��32'@C+rt�Izl��uz[��g�� �R(�xzU�O@V� ��0*���e�r�Pz6X��/����N"?��1zh��&���!M�w#�61Ho�2��-�t��I)f���M[�*P$눕*�!~�+��KB���dҠ �υ�&�c�G�7ӯh���@��Z֙��ʘS�� ++�@��XAPA�el�� x&�[�y�hjG���J�K�3zЛ��R6+��KP�/�Pp�8�gJ˥MI�`R�{���a ���Z��R�P���0}�$ɣrtP��Р�����ؖ�=^e�\��!�:#8�Ԍh�O2Nh��}!(�BwOj y�E/�#�d<E��m��`����O�_��z�!Й��Iqw�"�D��d⑮�U����@I(kC���d!����ہѱ���Z.��aj���b������|��/��KYi��Cf4BB��Q�-d�F�dR�K���d�N��#���������h��w#�H/d��f�?���x�_���T�~���Ղo��c�r��GHD2�ȡa�m����Y:Z1&?��cj.Mz*���� �IDAT�\s)L�v�yݹno�'�� ++��K/R<2)HovS��%k$mک�ރ�k�#��/��2U?����|��t�1��F�9í�(�;��"2���g�N�15M�HΞ�o�*��о"�˯�gcIN�$���R�S�������c�eА� ++���q��k�}J�I�j�e� @�wd6��B$�DY�I�t���FTP���.��f��'������x���� ++������|9��RpW�-�����}G�� ++��f��d�N�7�ܵ��"6��X�s�(t��Nζ�|�C�@�.���U�H"-,����1#S���E���N�BRM�T�l9�߃'�r�5�ێC���l���B�bt��z��)M��졄�MF�XXI�sb&�DC�̩����O+��n��C� ����C�<�|-�@(�p0ͩ`�������-M��G��4T~�G���� ++�3F�����l����X�v侂l��KE�D�ɮ(|#�(��A�&���M&ѕ�$�T�r����-��ct���z�1�r�3ɍ`��䔛�DŢ���=����h����S��4T{�v �ׅř�M�v�I=(��2L(�CE�r& �z��?�����C�}mkc��ǀS���֤?�=szs���Ӽ~cGg��>f̕��:�\N���Ko���/.QP_`gT3�2Ci �L�_(�4����df^��>O;S�C��ef=:İ ����)�mQ���x~Y"fLCD�uF��4g�K�j�g��:x�\�*�39铤�Ғ�Vp�Ku������e�`S2<�����:8����#�����Kɐ �eU�n5��yWV���+Q�)@�6YXx:0R��dN��rs��}�]r����U� O��C�B�(tz7|�p��EPE��RM�f� P�>7օs��Q{���D�ĉ0zp�e ++ $}3�w)Β'~�Q8&�d� ���1 ++(��v����$�&h��+�Q�#����n��|�d�`6-l�zTF��v���)��L�VgߡF+�k���O8�3�yƈ<̏/NY6o9��`��c���c�����#DT���d^'�Q�(=��6��<�a��:�|,ISLr2L:�*�!�\����nL$���"�a��´VIh:���D�̛���ص*�쾄ب�NL��@o��*�&��X���<�;Aą@�Q�nam�찈�<Kl$Y;����ʴTJ�b�\ ��N���i}�^�k�?ڶ'_S�9��O�鱠/m��%Cwԉ! �~����e*�!O�],��T��� ++f��Z��8�:;J���ڱ�@��I�{��0�0��.��|�b�ya�Q�r+�b-� ++K����ۉ)%��̸�J�1>�������Cb�H4PXӫ9�v���������$3�Qs��$�:eեN�v�/K�Q{H�r����S�i���HSI2�����n���X�y2��i�R���X:#�t�D+9e�����e0��IFL5�$�Z�\.�㴈Ǩb�\vay���0������!�L71��zT1�T3!��iM�-��/���/�܅�cFN��t7Å�тjNx�i:��e}�3"s*�ڱ^��"����{���ˇ"�y�������3�l�ѷ̑���������X��:�j �<)hL�&��j=��}�.W_lm�O2���`_��ݤ�l�� ���������`�0 ���1F�FF���Mf��#�����c�����M�v��a�ә|�$�.#��t6����b���#6e�͙��l7@ ��B�ĕF�B{l�4{@�~�.2������C�/mk��8�!��a����<m��������dL��ݬGﵛ-C:��۱3��A��!�}a`},�3H���A�.c?F��,X���t��@aY�:1tb��aQ�,:Ƅ�������I������^�b���HKϰن����?~�=%��ή�hH��?���Y ��s���H��>�� ����� ����� �^d6`�*j�ά�����:Ј,�1��>&I�:�=��Q,���-L 2��S�z����5���~�����%�c�zV�WT/�����.�!��u����+S������"�A��|������\rL��$Y�@��}š��h���8���@ԋ;"й�IF����Q&%C2�G2�6Y�C�-N�!��@X;z�#A�5ߔU�+�d1oҷ{H�����*U.F��lt֫��<j�,F8�����a.�/ҤYx��@Eޗ%Y���SD��B_�ь���M��6�+�ɺBˤ�܉��)�e��A/6(c�g��gMeiN�0NEY�FX�y��Kq��(j�B�M"/� ++Pja���Z0"��_Y�,��m��`�J,a���3�ZF!F�*��!�C�J3��K���&4]�"ۤ�@e��-ڦIP"���Je�,��Y�O����C�L�h�����5x�t*�R�G`���an@����^꼮���.�{-%���]K%���W��#*�?�kG5�d&@�>$�(G�oQ��X*�d M��%{Km�b�1�r�,͐5��<�9R��(�R�W[t ��~��`���fX�%ʎ}����: �1ar�*�L+~��.��~�d! n��**�m�J��y�hS���Q��9�"�B�(g!d�LF Y)Q" ++� ++�'H@��}k�Ouu�<!�֘����h� Tf���ȿ �ju�Z�g|$H&ʞܥ2ҥ.��4(��l9Cu��-W*�-��u�d�d��x�w`�E!rK5��.5I��͑TT�J �>M2yZ�pdTxD4�/�o�h�[ʝ�z��H�l8˱�L�����[�l�U��?�Fy�,e�+$�Z�����$S����r1w�E�4���_TS�D=��5Z_$Q��PKad*�/���]�""��j��x� $ ��3�ه��'���T�q �:�ͻ�H?}Dʰ�T�I%���b$m�Fb`$���AxZ �(D�0��B�H� ++����S�ۢ�G�rd�{���]"�X�%�ӤgP����dJɩ�Vm��t����$./����e���Q %dY!���$���Xj9GGD:�*�V��y j�X��4��c��12�dp-ZTf��ݨ��H�ZgfL3Ҏ�n!��i~2�$�i��h��ꂶ/9���8U��K�� Y�Ӓ�QKbP������b0�Eo�(}�G���Ǐ�|�G@<x��^�5��{����0'N��+L4���ſ�����w�Q�8g����WTT�#�\�ӧOGTZ �)?"QO�U�V�{���w�s�=��;�8�^\����.]��W_I>UZZ�u��X�}������C=ztٲe_�5�ښ ++���gI���+W��R+//'�7m��������'�9�$%����IVRR���o�喔���7���?��������^ziΜ9�S�/����ٳ�"P6�jD������z����嫯����ߒ�w�u�����dggǢ0��Qm�6l�C=�+W�\�d��/��f�����v��V+��>}���0++��o$!������Ǎg��HHEEEMMM~~�7�|3hР�ӧ�,�{�����I�&�����:uj~~>���#GN�81z�h����9~���l���ػw/�x�ܹfs�_hee�={,KJJ ++�x̘1\�����������zʔ)�ƍ�����?�x�'N�8s���ɓI8Aqq�S�F�%�-����?r�ȡC���c�0�'N$())�={��={Ǝ���p�ĉ���{�^2�w�С��������n̘1,��e�9q��^���3�L$ǣG��<y233�`0`����Z��J�F��ð1�O����~��=���ӟZZZ�������3f�������?�?�������㏹G�^��O?��x�}�].p�o��fNNN]]݂&M���O�?>''g����<��<���߯Z�*--�b��Y��W^�馛���W_ݴi����������O�0�����}���^{���۰aCyyySSSrrrMMͷ�~�n�:�8x�������������4hŊ�v����������b����k/����ٳ����{�����!��k�����.�W�~���� �q�F�\���3f��������������q�����Ϟ=��_���?|�p����ϟ�aÆ�������/��bSS�{>�����v���W_=x� �06l���hjjJJJ������֮]��ׯ߸q�I�N�<�p8rssG�m�Z�������M�������,99����O����5kְ,{��e����?��UUU�7oNJJ�������+W�$]RQQ��矧��|����-Zt��W�^���k��+Vlذᦛn:r��ƍ_|�Ņ�\�GyD�� k�0a�'�|�����������֭�����?wvv�|�͏<��ܹs!����+ӧO�'�|rӦM���l�ׯ����/��/&N�X\\��{�=���,p�\�>�����^{�7�|�������,�^�xqĈ����[I������|U������3g>����j�7o�k͚5�^�����,��o���3�,^��СCO>���ի�BݟCA�j6�$�zC\�N�>����W�nll$:�࣏>��O���?eee��z衇H�w��i��v�ܹm۶����YRR���>u�ԝ;w�^����˕����w��~��-\����,d^^-#F�����z�p8������d�XZZZHdR�L�2e]k֬���"�̛7O�כL��������߯_����'rŸ��***:4iҤѣG:t������rڴi$�ܹs#5��������dY6==����1ƭ��\�����J" �$i���<���`���W]u����7o|��e˖��W^y%55u�ΝDB��uuuF�q�֭�rʔ)F���ŋ+W�0`�̙3sssO�< ���������$��X�`�{�7dȐ��2��M�/������~z��3f�:t���B����b���)t�5�\c2���� ++'M������?ddd��f��4d������ڑ8���ӦM{��7���v��1lذ1c�($ShC2�����?>33�O2�мy��Ν�~��������[H�c�=6bĈg�y�;��W�aÆ������+�@Bܿ��o��f�B����ݻw{�^�>�������=z499�����K\�X�zu^^�r֭[�<;����w�^���E@z��<q�ģG�;v엿���n�裏233�L���-�YH�vRJJ���kרQ�z衰��Q�ˆ��|���K�.-))Y�j������o~�{����Vbor6�#�<r�M7]��/����L�<��w�}���MMM�Ν#"��t:����{�r�qs��u:�����K��n�ZXXH_��;w�7�z���z ++!�r�:::jjj���O�t�v�mN�s��.]ڶm[QQ� ��ر�a�1c�L�8���o߾}ڴi�c�B♙�Ǐ���jnn[)�߿{��Y�f=��?��Ϲqt������d�^�b�;3����k�����>�o����V��={�ڵk�}�ٜ�~��{����?�`֬Y�������t�MK�,9|�0��\�����;�x�嗧L ��2r������[�n����}�]2У�̙3��曻�{� 7�|�%K���˗////_�`�_��ɓ'+'5bĈU�V}���?���6l�p�5���{�8t���b��L��0��d*((��|�AF I�G}���hѢE�A�t:3֬Ys�]w-\�p֬Y���oc�僃c�ǟeٺ������Z����jkk������|MMM�pe7n���;�X�j�ĉ}>_uu������_>���\d�����6p�@��|���f����[`���N����h��>}z���7o6�D���/y���9���bI�pEr�ӏ?�0} ++&�I�0������ ++hjjjmmu:�������,� ++D��h�d��N�� ��ONN��)JKK�^����l���Z�����ei9��I$o� y�7����F�e�F�O<�h�"��(�� ��$�t:���ݻw0���m�С���﮾�j.B8������{#y�&��p���[,��&�F�V�B�<�������fee�E�0����Ԭ�¤��㶐8��="j@9Г,�[�� l�Q �QA�^$��K��g����ɺaM"9�DD�H����R=T�J�i�hR���(AYH�,n���[�L�,аwU�n�x�d$v�� ��ݮ%��W"��,�4�� b�0��^�$�È�Ģ|$S����!fb8Ҕ��'H't��ڞ0o ��k�)ldM&X���� ��g��Bngvw9��"�'.d�d�BE���99u{���P�a�� #�u�&�/w+A�^�n�����eK�Km��o��c�x4�'&c���1�"1o\i\�oW(ɮ4B�Z��M J�5���l���1q ����9b:��C>uS"a�G�^Ի= �i�����=A�^��ȳ�����'� �,]z�0K��W�w�,A�b��R �u>�~��}>IH�� xyԽK �i�>��T+� �f�'�z����:<��q����j��`뇮�e_�-F-JKHR�݈�1L��G�����yy�só����x�-V^�#u��g�|c�'�!�,�Huę ++xB"p�:::�[��eq��/$�u���HU�r+++�i~b���|��q�%���۶m��YpLI�n�����b%ҽqb�T�xyWW�c2��a���c�aßw1o�����-[�466"���ӳ���O�N�K*//�����nr�����G�]�p�dU��ʸ��,�СC�M�Ɲ�� Ǐ�?~4-�>l�4�hoo�x<܁K��dr�OSSS]]��ѣ+++;;;�b�<X��se;{��S��� �*�J�}x\Z�����0��_�u��8zxjWC��m ++ ++ZZZ8PTT�lٲ���2䮻�;v���8�����믿>99����������?����D����1'W��{�<xP�Ӎ5���s�μ����,�ݾiӦ &����ܹ��p0��p8��������l?���Q�4)�T�ly@nt�赺�~�甝nl�����3O Q����3g��[n�e���۷o���|>��h��|DUUU]�t)55uԨQ����4999�@g�&M"g1:t�������;|�ryy��F�M��������c������t� ��d������P�6�W���u߾}+V�HJJZ�n]yyy^^���z?�裬�,� ���Ǔ�o��VQQ�w�AJUZZz���@CCC]]]vv���ڪ��dUm�����9���,��ӓ!ڽ�.�BRRҌ3������N����.]�tĈ��ş���fkoo߳gϊ+�G�~�������α�`�����?x�`vvvuu�ȑ#/^�����;��|�������M�:���n�3g�|����W�]��Q'����e��rrr����yyy.\ $�oݺ��������<9�dTVV������t���/���f��رcѢEÆ S];1������A��:�1��L$ b7466�]�[qq�#��>�qKK�K�/�hmm}����Gg������������ggg8���b߾}�<��fkkk[�zuii�UW]u뭷���3�o߾]�v�t�M>�o����Ǐ_�`B��/�<r���(��V��n�'%%�-K[[ /..v��V��;*� ++�=�r�,w\����G�I~����s�=.�K�1�rP9���4����-����A���[:C��*��0� POÆ �x��;����GPTTt�ȑ�������~��W|���m�222��>��ٳg����?~�ҥ��䪪*�Є ���w��}�������F��뮻��=gA+��̅�g X��^H�dzx�b�a����E?~��e�|����܍7 ++��S�VUU���ە����S�$�>�-ib����;�,ty�0����6#WilL����� �9s�ddd�ڵ�~�3g1���믿&f����,IDATR]R�?���f�y�ڵV�5%%����;z�(�0p�@���r�>��Ö���c�fggWTT�,�p8��b�D��?FZ������Rr�p88[j�ĉ#G���|�}��5�\�����������to��VGGGGG��`����4h�ʕǎ��On�������ʩ�d���YV�[o�,���e��_-�,��l6�dB<��3g�ܱcGKK �5k֢E� ++�^5��z� 7���@FF�^�_�t)y}|���'>|���~Ŋ��~;g��p� ++�~=ztcccuuukkkYYٸq��]��Ǝk�پ����x:::��ӭV+'�B����c��Ƀ&���K%�JIf1�og�_H�\=�.xv6�,�����~��Ŗ�������z�o�߿e˖k��fȐ!&� !ĩ�o��a��#Gn۶����[���#G�|��W˖-�8q����o�>s�L��s�O���z�^okk���ݷoy*///55��o��7o^GGGQQ ����/��i�Z��� 6�,{� 7dgg"�~��o���K��������(99yȐ!K�,����ϝ;�������155��;�TW9�7�'���7_��ҳ���6���t�RYYYZZڠA�~��� f"X��߿��-[�n�^��7o:q���;]{���n�A��N��;w����̙q��-Y�d�֭��!C�L�0a�ԩgϞ}����f�5�\SVVF���{�l���o$%%�1"R����r}YPP����1&#��C���������p�UW ���v��f���n��֛o���t��8�Q��K>�(g�l�-fD��c��֖��")� �o�v��h4r��0�v�=55U�~8eF�L��%+.XqqqMM _hEZx�e\��]���%����gm�-�����+KO���kYD9��)�h"�rg��5����_�P��B�2h��Z�g}�dZ!J�j��(����)�Y�_~�� �P�0�G��� ̈́$�q�l,,���i �I����&{��TF�W�������J���3�\�+�d�j�8=��YL=���BI���ԤLJs�iU�t$�B�z8bʰ�� Yx�.�� ++м� &H@�L�Q.%�E��ĕH��q��]F��IF�E�hнIL�ʢ�2LŬ�j���#@���yy$�ƕ#�T�^�%�eT�waO[BH��� 9��V R"n�:�.��ҕ��>A2��K�9Z��#�.�:��}*Z�a��=� ��f[*��? ��L��d��h�W�����HƌiI$��>;K\Q���K��V�hJ�����i��D��V�kB�W,��hHF�<��v�E��O�ĸ�лe��a���k�[V���I�$�������^�744���J�mnn�������MBH㔕��v��̙3N���:s�̙3g�����Ν;��������R]b���K]�8���䷿洯d/`������zSs�ĵ��[�n�?>��PTTt�ر�z��7ضm��b��Y* Jݧ�p�����?$��L�B\�@Pc~�嗧N�2����K�.5%%%[�l1�LIIIK�.5����}cc�~�+ҪEEEX�l����������wtttvv��$}z�����R��G6I�0�0�Z�>�p{-{d�V}}=˲���&�����֭#�MT;&�߿MMMEE�<s���˗����c|��i͝�MMM3f�x�gy䑢�"�������ȑ#˗/ꩧ\.י3g0�_~��w���SOY����p��?��#�`�O�<�O???������RSS9�E,˖��g� �N�jllԼj*I�Kv�/��g�����ܽ�o��;u9���$���<����}�v���8UUU���;q���<�p8N�>�y�1�L������_YY���_���V����?����n���>t�8MI��t�ر�'O��������a�����^�OJJ���kkk=z4��=��233O�:����F�QliI�y�,//���HNN>{���{�ĉ 6p�����AT�K2�����Bԏ��0iqǻ����r)h��f��u��e��<yrYY٬Y�jjjBD�~��g6�����b�Hj�n�x�x��)��2h� .�l6Ϝ9�>:t��h6lXii��h$V+�Ly��ч���<u�T~~��=]/9�%���H�36�W.��Xd0��zҙ���6�%�9&��Ŀ��/�~��%K��/Y����f�544�|�K�. <8//������UUU���s����|��_��W=\�655}���7�|3��v��ĉ��ͳZ��������p#��e9[IIIyyy'O����Ǐ�Oy���>��ҥKsss7m�Dl�����lʔ)����dL�!���?ܻw���ܹi�h�GC�+%��cb��Ʋl]]]yyynnn^^���|�rMM ѕ&L���9�������~~~>'i�;6hР�'.Z�hԨQEEEiii^��L?�j\䂂�ݻw���&%%���<x���uuu���uuu���N����O|��'ǎӶ�*I����_�ǡ�~���6ݰB?j���T0ڍ ++�p����s�̹뮻Ν;���� <�ĂD����z}uu��˗���ȉ/��� DWJ(�O���c�p86n�h�X�M����J����:;;�z}mmmgg���kkk#��G�z�^�V�K�H&M�����EEE�����ӕ�P\\���A|���\J���|?{���{�Z_�>�@�9̔�R�;&�{�&��'L��k;v����Y�feee}���w H�N���s��q��?d����ͽx�b{{;߬���������_��Ç�|�͇>|8�=�W�ffРAs����n��o�9r�)S�tt:�/~������{�B}�655)����� �J�!�U��-��_{�_{FGw���(�[��6��СC����\�aÆ2�W�jkk?������.�ٳg�������c�N�<y���:�X�`���!�g�}�gw�u����}>9����Ȍ �?��C��(��X��nqhoookk#�!�3��r)���e�����DC�~�7��J��_`�>+E���;�X�n��11Q����������4b9���ZSS���BH���PSS�p8�jkk���\.�����^1�����z=���l6��e/^3f�%��x%�S��g��� ~ �Cf+P��h��Q~ �2��#�!������C�$&����1��Γ{�7��U��`%��=y��V$��o��yO�QP��☸�RJ���ɭ}[���TP��cѢ��7�D�OR�,�FPz�T�eL�S�$ko�]X�_�d=��1���G<�S��;��x&I8*I�zj҅ј�*R����5��Q�gj�eO+h^���ww/��h�6z;A�ϔ�3�#�+(�3����>�(��4P��J��ʷ{8"*s��cZ5M:Q ++���^a�Rc��ȵN|[T)J�K��4)�g!>�hm2��"g��F��.1���ӄjQ��X���%��3H���V�@�0O��a���;��#���W�z7B�%�!4f)}v��Di���\��+k�~�왢� ,c�ۋR�E���"|(t�� k�GT��]u9 ++եB���?u*,z�%����n���e�Vl�)��`t�A��}��$�^oF��&1��D/�h�@ٶ���l����4戺�h�XL��v��e�b��f�W���l��8����)!�ܚTf�K!�2F�0%��\�"�ߓ��C4���e���[z�� R�ۋ��D���g�t��K���M�<�|DY�M��F���`0��r͆i0�;����IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/en_US/index.md b/data/ukui-system-monitor/en_US/index.md +index 7f80d6b..207f8ea 100644 +--- a/data/ukui-system-monitor/en_US/index.md ++++ b/data/ukui-system-monitor/en_US/index.md +@@ -47,6 +47,12 @@ Dynamic line chart statistics system receives and sends historical data of traff + +  + ++### Disk History ++ ++Dynamic line chart statistics system reads and writes historical data on speed, with tables displaying disk model, capacity, disk read speed, disk write speed, and disk type. Click the sidebar to view the disk details page. ++ ++ ++ + <br> + + ## File Systems +diff --git a/data/ukui-system-monitor/zh_CN/image/4.4.png b/data/ukui-system-monitor/zh_CN/image/4.4.png +new file mode 100644 +index 0000000..a20601b +--- /dev/null ++++ b/data/ukui-system-monitor/zh_CN/image/4.4.png +@@ -0,0 +1,134 @@ ++�PNG ++ ++��� IHDR�� ������P���� pHYs�������+�� �IDATx���i\T�����U@6A@AP@qE�\P�-���\3w+�}��4M�Sq�\B�TT����}������o�"�`V���3�{�z��u��ð,K�����&.\��������o������fX����j������fX����j������fX����j������fX����j����P(�9ZPP���dddDFFfff��Ԩe@����uQg�JKK[�b����_ԡ�����o�رaaa�y����Y�f���^�v�5����P/Q��%IQQQ=,--utt�υ��Ǐ'"__�w�}�v�7nݼys�ȑ�z�DDb�8$$������������%+22r�ҥ�t�����ݹ���ރ ++_�j�/������ҙKE��־�� ��G�]�~�v{ZZ� ��ʊ�t/���mooߐk�����KV�03w������ϫLSݿ?""���Ν�Oz�/''gժU�t�����|��{�"`����������:���u��={��3fɒ%�;_��Fppp1bDHHȮ]������:|�0������5�.`mm������.\h�U������%K( ++�B��G�����USS��S>���ӧO���TTT�+++맟~"�/������4~���]�r�Y�ݿ�v��w��0L�����,�����4�abb"�n�Z����$ @�E�P899I$��k��>�>�>}�̙3������w���ۈ��\�~=���sΜ9�۷o������o@C�D"y���l�R�]&���믵�߽{��qjh�իW�ӯ_��{��[��ʕ+W�\���Og̘��E]�����#��P@�S+K ++���8]���'^,K�Z���$R��^UCV^^YYY���*�kjjN�4�!#�,[�=++�zN���0̻�۵kףG�~��w�w�~���m�^�������R�,H�)"OG�@@����-����_mNK2���}w�/��J@D��)6F�C�hp�DB0�/a�rX~�_�����g�Z����5��峟�,�2G��PQ;p���8���:�DCVFF�^�����h�"�s^^ޡC�F�٪U�:G ++ ++3f����@Р�r��Z~O[[{��ɝ;w���>��S�+����Er3F�RR��&)�=yW�~JP(X�I������S2�����Dr�k���c�����y)��<����CHDN��Ѳ������\��lv��j��|Q�HAD�4�N�4�DD�̎1j����!�X�ڵ��O\\ܾ}�����]�fll�r���ۡ�����u%�gϞ�,��͈h�ƍ*3g<kk�={��4��b�öm�N�<ɷ�7�[�n�����hj���X�Ez.���|���E3�f�b[�����k��'���Ȗ�v�g���}v���>��W�+� ۷���������e�msC���%��xy�����͘�J����ְ�l����}�#�n�Qi%-�M>���ܐ��D_=S6 ++X,�FGGS��*Ο?OD�Ǐ�3?����D4z��:�Quu��^��y�fC��D.r�j�����E�U�w��p2fRs��\�t��ш9Gaӌy�] Rd��=7�8�OK&�1���QE5Q�=E}�py���e,k���"[3&,Aq<Q�d��>aOg�[2�6_Vl��y�KPh ++�!���"��%�j9љT���_;���2V�ֳgϲ���(33S*�����Ɲ;w�>geeEEE�����>}��o�ѠA�^t}}�ŋ+����͜9�!�����<v��9��ɉoG�Q����ݓ"�F>��P�� ����z��B"��H�]��j���;N��SC�,�w�I�j� f1:L�EbKDF:��L8��`pG%e+���,◴G�(��(CB�; �?`��Q�������c��"��������f����x���ի�������ND}��iӦ ����>}zȐ!&&&Dt��"��������/Y��[�n>>>���͌��'N��^\\�a�"���Un/--ݺu����]]]_t����^�+"����]L��fLB��[kAv�B�PQ%������bVƒ�>Ef��7CM�KK�LNլ�s=���Q��W��TUCW�)�葘%��T�P@���a'H�c��2Dl���{O��?ǜ�Y@D��j�f��r�����۷o߾nnn�JJJ���GDS�L�Z�������>}���r���ԩS������ Y�p!7�U��~�M&�����r����<���bŊǏ7������@[��y6]�3Dm-��, �_�/��5TYC�"�������^Bg3*����(t4"�v��'��g��������1�,]HW�OS$=f��Θ�5a�HW��w\}����_;A�7��ܹs��M�6ѥK�>��S�ϙ3gJKKХK"���?��#�=�Y�f���������/���Q����hIIɦM�����\e ++�/�pppذa������ץK��1��k������je��Vе{����W��������ʫhbGA�''d����65D6̉�y�&���u$!Cf�H����;��="��Ox7��q ++�S��*4�kU{E5M�Y&���U�<`]�~��EEE[�l!�Y�fq������҈h�ر ++��{�oy���DTUUu��"��O���kXSS�j�*���3�����jii}��>>>[�l��矗/_�n�: ��մ������� �?e�<�s�T3]J�g�`��h���#cn�Qh�|K���+��@�ܛ3�z �h�IY+S��=��%cSW��dEE5KDمDDg�BQ;k���j�Y�j�S��$`�����A�Plٲ����_�~B�011�����O�ƍ���������nժU|||iiiJJ�X,�6�ʪ�������g����#꼮��y@@�;Sp�B �s�Υ��3ò,�根�yC� ++�����<+es�o|�Ed�Ø�ѻ-��#v� ��Eg{��>�.����Q�Y��@��W�X{Q.�d�i��j���.u,sJ}�n�"�j�Qa%���KUfl퀵s����3XN�HM^�~������z:���q�8GFFFFF*7n\ii�W_}EDR���?T9jaa�2ZII�ܹscbb����l�ڵ�vѵ13hР6m�p�ZXX|��g�z������6ގ�q�LE �[�q{�����v�&�}� ++�%_?R�0���,��@�LuGSFXD�l��� ++"2�f��29urQ����O�� z���[������Wg�E��_9M�֧_�,�ew��ADC� ��Oǎ�Ϻ��NNNiii���}�����9�{���ĤM�6����;��F��=����СCcbbڶm�e˖zv��9::r����͛GD���zzz���]�v�'�����(<Q��3e�x���vD�)����b61K�Ҕ�/g�$lwk�{��Ɯ��3�ER�,8~K�nŔWS'�+(��D����ڶh����E�F�T��4<X��- �X���������~�����M```�֭---���<x���GD�Ǐ�:�?~���666\9�+V�����ߟ��P���������cvvvvvv�~���;��eٸ�8"j۶���Y�������d����hO,;<XFD���p�����������w�2g�:Y2�Y������Ɣ���l� ŁQ""0�j���+|��Uk��/?f;6g,��H%��c����hѢ�>\���ڵ��>��C~;B~���=zt��q"������ދ���:u��n�A��������禈t"�`��ù��4jw�I(�Ð�% !5�#�c��DD�>UV���ИZ� �k!�� ��|��9sf��������y'D0\IJ���M�������'O��P(��Ɖ��?s挦��re���D���ӵk�ޟ��7W��U�rvvV^\������c}}�w�y�o,,,��?x���x3�5l�?���F*�I��0&`�LW/"�����F���j����ˣ���Vee�K����7����>}�����������߿��Q"�={������{4�X��[���С�T*;v��ѣ��u��8p���i�֭|�;wF�������P�Uro�����7o������|�͝;w�;�ܹ��F����*�<�������=���b��~KD˖-����6�Q�Ps��Ymm��ӧQ�=455�;VVV������x{4n5q��% �Ȳl```QQ��ѣ�mm:t� Μ93w�\�@P^^���`�"2449r�ѣGcbb^�[����?T�f���ӓ������wY 177��|���TTTxxx<~�8##��������777nQTYYYff���5���/��5����o���`�߿_yg@==����e˖�������322RSS�����<x�}�v"��И3g�O?Bdd�D"166V�O���x;4.`�o�^�h�B�2dHEE%&&�;����'&&u�/����������斞�������ԳgO"����6�!�G�qBCC�7oΟX]]MD111r��vgLNN&���|�-ENNN�!""��Ç�goool����M�aٗo�SYY���AD7o�TXD�~��w�y�}���[�������255-,,�������7o�w�}������fgggccciiɕo8z��U��̙3{�l"�t�ҋ ++h��{�Ub����M� ��������_�HWWW�аa�F�U������¢�������ի�����uqq!���B���ΆMA[[�I������`��'O����kh�Q��S]]-�J�= ++����:��j�����455������GS[%w����� `��������:�:u� �����1�,����uZ�b����:y{{#`����Y}u��M����kj�R�(�����P3,����5C����P3,����5C����P3,����5C����P3,����5C����P3,����5C����P3,����5{��U]]���+�Jk���YYY999�3~��b�����>,������V�������}���l���ӧO��kcYv������z�U;�esssKKK_s�B��[���7�Vttt��5k���y�G�=x�����]�ܸqc���~~~={�\�`AIII�NW(YYY�O�~���;w��D� ���M���T* �ӧ���nill����&/�(�nݚ5kV�>�iӦ����?������#$$$>��o����j��������+99����S�Nj������������x�m�}��YXX,Y���յw��˗/������m�nnn.\�p�B���>����^��7n�������-YYY���b������ãγ���SRR���Z�n����E�������:�=KKKo߾ݬY3777��ٳgqqq&L�{������066655��Ȩ[�n���DTPP���jll���|���EEEqqq"��S�NYYY���R�������S H$�+W�<}��U�V�z��������֭[���777�С������������'���s-���S�N���������277'"mm�F�?�����+,�\��G�-!!!�~��B�hѢœ'OZ�j�rJuu��={���ۢE33��[�zzz������������^��dɒիW�+!!A$�oߞ����1w��e˖]�z�ҥKZZZUUUZZZAAA�۷������/ ϝ;��#�L��_r7OD�7o���'N\�b�P(��-_��]�v��������D4p��5k�0� ����t�Ҝ��G�I$�o��f���D���#"�o��:v�x��5�B!��W����o�W|D������kW�klll@@@������Ξ={�ʕ{��r���{��^��̙3?���'�ܹs��"�fw.^���� DԽ{w�������?9� ������ ��� ++ ++ ++""��Ç�����T�sjj�ӧOG��?d�w�ޖ-[v��}�ڵӧO���Y�f�ĉӧO�t���˗�t�r�ܹ��d�QQќ9s���������s�ܹ1c�,[�����DTXXHD��pDԼys�L����E���������⬬��H�Plܸ���/_nmmMD��r�����[�:t����TP�֭njs��a�DbggץK�+W����?��)333����4""��bʆ��W_YYY1ӫW/CCØ��LFD���#��W���*�l۶�S�NB����� ++�bٲeC����1442d=x���|��ႂ�4oޜ�D"���P(�8�ݿ�����FFFDT\\ܐ{����WX�ϟ4h�P($��������;�~,���Ȑ�d]�t�PbeeEDO�>%��C��͛7��qqqD4`��~���$�LֱcG��---�?�@ ���V(�t������Yhh(�]d2ٯ�������r� .�����H,s_������---�_���������C"�� ,�*��}�o��{����WY���������_p_sss���tE-NZ�bŊ+T������7EDDp��.^�����?�$�ku�֍[�]MMM"��sjhh�9r]iii���Ϟ=�?�r�Q������L܀D���t+((���Yyy��!�DB�c������_�U֭[�ttt���\>�փ����-X�@93q������<w�\AA�B��r��ȑ# �>555aaa�g�n����k]ׯ_www���&�=z4v���������ٖ-[Tqo������\Գg�D"���1����{��5p�@������ݻ,��ک� ++H�Rn�V�|}}ϝ;��� �ˉ�o߾����Ԓ��Ν;7�V���������&O�֡C��%�:v�knn�����M�%%%��ߟk�H$III����g�����e��~aaatt��<���i����ݻ����7{W��v�ڵn�����*�4+?�ҥ���^tt��˗ �+i���:888884�n�������9s�L^^ްa�;� ++n���Y���vvv������ǂDt��5">|�k^����A=�ť(���0�̙3oܸ1o�>����:99y]�g���,[�lʔ)S�L�5kV˖-�����7;;�q��q}tuu����G�*�I�&�3d ++�",,lȐ!/���YCD^^^�0��DFFn۶����O�>:::<8z���ݻ�UVS�L�:u��_=v���ϟ�Y���ӳ���z�>}�Kl�ⶰ�0ccc�H������ތF,�ƕ�����?���U��������{���ޭ�xxx�8qb�ƍ�-�Z:v����<N߾}>LD�e�>|�����<[[[�����ի={����|�Ax�`ݺu'O�ܽ{�ѣG�HKK����u�С�Ν;W�^=m�4�@���x�bn�ZmYy���ۉ��������Q�)�����v���ϒ%K�� ++*X�-((`��Դ�KVTT��b����駟���.^��VmA�P(�={�0������2�e�>}j``����������r� ��`ݹs����E<si㥃���lٲ��x��[���@ �g>�a�ן-�����-r���Q����ݾ}��������и,ooo__�&��: �[��.������j�,�������\�������j������fX����j������fX����j������fX����j�w,~������)o~� ++d2�T*�������������1cƌ��B������Ǐ��Q�'������+55��n)))YYYu���_����?��.�ɞ�@qq����M,��Q����k�V9 ?s�L喩S�N�:����ɓ'�w�^�x1�,{�ر����;VVV:t��z��)MM����W��...={��*�m۶ݽ{w˖-�۷'���§O�rG�<yBD\������Ɠ'O�^�7n������e2Y^^�������r;˲,�2�0�r;7�Ƿ+O� /ɾ,�N�>���w�ԩ��O���hR��*���$'''=== `���fff͚5���&��g�._�Hp%�� �IDAT���_~���KOO3f�����y�����{��ݱcǮ]��,[RRbdd����9p���)SfϞ�r�e˖����ڵ���#""b��/�Ɉ�33��������'z{{O�6��V�Z�~�������p��d2�����ɓkȲ�#Gv��U^^���5iҤ�S� ++�B�����/^�`��1c��ܿ��?���w���qVV�r�344tpp���4h���m�+fff���<x����E?���^�kn���,CCCWW���L�=z�����;wQqqq˖-Ϟ=+��۷������ϯe˖�����c������3gΜ1cưaøi!�Tz���:��v��/��"<<��ã_�~�n�����|����Ν377�Z��!---;;;�HddddggGDyyyDdmmmkk����x�b.'���|��w*SP��ny�̙={��u�ֆ ����Ν����X,�?�P(�����vgg�)S��,[QQ���|�С�{������p��Mcc�������S��ܿ�[�n|4��ϯ��a����ٳgDdaa����}����*O�����ڵk�ڵ[�n��֮�zzz�}�����T*�s�ߞ��ID���&&&D$��MLLڴi�w�f݈����Ç�����у�~�x��@���;w4h�ԩ�8;;���8p`�����K���˗s����^����e��������ӧO?r���իU��������Ш�������9��)��Q'��. ++ a�=�������ϭ[�^�jUll�m۶n�ʥ���¡C�nܸ��ӓ�VZZz��9"*++#����'Np�z��q�����P"���&�;w�pG{��iffVYY�� ++����b���/�T�CC�o����\RR2bĈe˖�G������T~}233��u��="�&�T\�r��������V�>}�9��L��P(6m�t�ƍŋw��?�_��܈(>>^��ٳgqqq&L�[rssccc�?nkk���V�SE���x3���O�3Rq>����BUUUbb���WJJ ++���EFFjii5k듐�P^^ngg�P(�vUUUqqqD$��������-777��d2"z�� ��S�N�=�1c�����͛_�|�������\$�v횹����Snn���_��ox����㼛7o�+����Z�ly��=n�XJJ����ʄ��ݻD���ķ�nݚ��|��رc'N�=z��Q���k������J{BB�H$��ѥK����+SSS�#G����8����@Sh\���x��u���4�B�w����ꠠ GG����u������رc�ܹ�����,--�/_���8a�33�����v�ڕ��`cc{���iӦ�O��R������/����ؘ[���o������m$%%}��W&L?~��ٳ�L����mff֥K����ᒟ���r���g\\ܤI� ++ŕ+W���#���^W����[���ۋʢ��7l�@D~�a�˹������Y�����!���M�4I���˗�{�=�*555˖-300 ��ӫ�� ������k�5X\=�~���ݝ{Px�̙�m���������/)) ;|�p~~�ٳg����<x��LJ+���Ꚓ�2f̘Y�f�?��%Gffffff��Z+Ndd���]HH��ի��UDԽ{�6mڨ��*..�X���+�w����ɓyyyϟ?��̜7o^���[����÷�D"CC�(w���D"�Lv���+V�*&&FyvM |��w�|���4""" ��ZRRR^^��ᡧ�GDÆ ��>����h\����Q?�:��$ɱcǔ[n߾�o߾�}�>|x֬Y044��?���}||�����. ++���w����'O���<~���<ȭ�jѢE=�ɲ�T*�:u�~�v�ڢ���'Or�[����^G^�(yyyijj���ܿ_OO�ku^���R)x!��U�a]�|Y$�߿Ϟ=�O�>|8�������Ÿ�����¨�����jԨQܟ�듔�$��:v��}555�ի��˗�n�:bĈ��2����4����.���妺��.;��|r�:VtttUU�r�X,�����Ԍ���D� *//����ŗ.]�8q"_jB"����oٲ��ʪZ����ҥK[�l���ڥK�-[�����S��a���?~<...11QKK����!�>|xTTTTT����� ���cǎ���|��G/*��e~�=��Ԕ����<Ѻu�����̙CD�6m�֓)311�ܹs�Ν�����������'�<y��~��\�v�[�n|� "Z�z��Y��=:x�����E�����h����>�TԹ����p��5k��-�{�^�payy�����3tuu7o�,Ξ=��������l�?������Ν�����PXXةS�����d߾}R���~��G�W���/Z�ED8~��@ ���ѝp�JKK�ǽɽ~�?~|߾}����i����x��A��������p�U�{�="��� S)�j``0u�T�3g��ݻ�رc���}���gd���h:�ߋ���|����-"�H ���pA$//O TUUM�6�̙3��6����>�,44t���D�f͚��P���?�ZOO�T*���窮���K$}}�O>��_ 7��Q(EEE���\��m۶M�2�;ĭ��������m۶�W����U�����y ������/�ǚ���G���Ԓ��Ν;��ibb2a'Nhjjnڴ �[���]�d�g��D"� ++.QNNΎ;.\x�ƍ�ׯ�ٳgE"ј1c���/]��2������-�H,,,lmm�'b\�uSS�z�~���o���{��~~~~~~���yyy3f����eYv���\���vVV֖-[JJJ�?���3f̘ݻwQ�V��S���K�.���������_t�=z���;w��L0""B �3�djj:o���#G���[�R�O?�DD:t�Zbcc�>2�,==��jnnnjj*��ry=#��@�i�J�D�����^�n�|`mmmoo��;�lڴi�ʕ������'N�5j�K�7~���b" ++ ++ ++Z�z5¢���ϟ���7jԨ�~��믿�q������(MM�����c�:88�l����:##c֬Y~~~���UUU�֭{�����#""��������������̙�~���[����;...$$��O?my=w;dȐ'N�ݻw���|y���\��jUU����CCC�>}��'�p%I ++EXXؐ!C�K<���}��ד&M����iLLL^^ބ �(���o@�ةS'" ++ ++ ++�~����=���_VV6~�����gg�>y����(55�I���355���&���䚚���4"JHH������ �[�nq�5��g���/^l֬Y``���G~~~pp�c�>��ٳgkhh����i�f�ҥ�&M ++lժ���W@��V(**Z�rett��͛۴icoo��������}��B��k�{����`==�ٳg�.^�BKK���?�9s���۹�XD����r�J"���srr�ݻ��������>|����R�j���r�<88�ۢQ |��'/�:���4�q��1����V���L�cǎ��s��]�~���������ZGG���k������spp��.6l�ܹs[�h1q���^k߾}�R����/��bݺuvvv�O�����;wn�^���K$�E�ݻw/$$����7n̘1�СC��~��� ��l�R�-[N�:u���گr�ry~~���ym��O?]�x���%Iiii����߱���^�E���ѱIV� ++ ++ ++LLL�r������555\��ŷo��իW�A���<11��ۻ����܄�OOO�LVUU�R1�e٬��:w�y3&M���ꪲ�"�������.� ^M^^ޠA�v��Qg4���5z̀�$oBS ++�[�n�����[/��c���+Wo����f���������@����������@�P����@��iprr�����:!`����ӑ#G��P(ҭ�������o���@]�\���Ș1cFaa!�r������?z���CBBz�ꕚ�ZO�\.k�\^{�e/\�PSS�J��S]]���+�J������Q%�����3g*�L�:u�ԩ666O�<ٽ{��ŋ��e�cǎUWW��ب�PYYy��!��S�455����^��7�����ٓ��s��}��5�&'N�8o�<�����E� 0`ٲe��� �W\\,�H�7o��2�e��I�0��57�'���˟ȵ+�ßX�����>�,**J[[�~����2�,GG�}�����l��̬Y�fD���3mڴ�˗��Gvvvw�ލ��۾}�H�z���;w��رc]Y��ݻ����<������S�LQX���@MM������b{{{--�ڷ'�J����:�����믿��믥R� 444��Y����ڷo_ZZ�2~��ɓ'Qdd��<q���|���ӧ��$&&�C ++���;q���������hݺu'N��� ++[[�6m�������u�jttt��?>����I�X���������:::=z� ++����;w�$����-[�={V $&& ++�۷o'%%���_˖-���ѣ��ɓ���gΜ9cƌaÆijj�T*=p�@������������m�v����͛��SO� �a��,Y�dϞ=*�p�8u�T@@��a�f̘abbr���={����|���B���v�:r�ȓ'O<<<^4����O�81v����_�}ƌ2�L"�DDD̟?Ĉ�/ ++��ݤRixx��E�����@��j�����w�֍�W���&??����a�gϞ������7���ß��@���e]k���غu닞vY[[��ۗ{j���dff���Q\\\�'�0}�����~ѝ80%%eϞ=���� e� 255�իw�ڵKII�t�RVVV�V�������������_�~�ܹmڴ�s��W��_��G�s��Qyؽ{����s�G�5w�ܐ��>�@e�������N�:5����@������شsDĴ(��NB�:;&%%yyyq�[�n�jժ���m۶mݺ��Ą� ++��q�FOOO�[ii�s爨�����'b=z��|�rhh(UWWѝ;w��={�������瞣�d�7nTVV��ӧ�;p������_)�Ѷmۂ��Tf�ꤣ�ӻwo�+�0�Z��~�zAAA�V�T:��Ԭ_����u̘1u�����`�;;�U�V����'����bbbrrrT֍7\]]��mܟ���B���ѱs�� � ++����ո�%����u����:,'�;�v������D//���"���122�������%$$������) ++nwUUU\\��b"*..澲,�0���9�U&�ѓ'O��*�4O�<����3g�r�QfiiY�o���'�������_�~ ���jjjn߾-����k���LLLܾ}{��qb��["�q�F.��/;;��T^������}��������?����֭[EE�ƍ]]]w���j���������}M?Ou���4�B�w����ꠠ GG����u������رc�ܹ�����,--�/_���8a�333nni]���666���'O��6m?C#�J���|}}gϞ]��D���]{ꨁ���KJJ&M�����y�foo��W(eee���?��Srr����k/cY��ѣVVVݺu�=Bee�e˲��G�ٺu�:�RZZZ\\,�Ɋ��/_����?�~>������kW�����ccc�,Y2j�("z��QFF���@�i�5X\=�~���ݝ{Px�̙�m���������/)) ;|�p~~�ٳgW�^͟�����AnV���5%%e̘1�f�?~�KlqK�����Sgccc>y�)::�����߳g�I�&�>}z�ر ��gϞ]�r% ����:�Q���$''ϟ?���nݺ��X�H���?�3�Ό�+{���駟��ӊ�����rtt�>}��������uN�����4.`1m���q��G"�;vL���������۷opp��Çg͚u��CC�?��#11�����LJ뙛��p�B�P8w�c����'O���<~���<ȭ�jѢE�K�,{��kk렠�:�?77w�С��gϞ<x������Y ���l۶�o߾/}�HD�۷_�b�ӧO��ŋ/Y�d�С*}�\�BD/���/<x�СӦM۶m[```�bW�-rttdY���433�~=z��͛]]]�>�ϟ4h�z���{���k�={���V_��4��,��t9�d��q�zO��'::���J�E,[ZZjjjFEE�D�A�]�r���K,_�t��>��I$����-[�XYYqA����t�R�\���* ++��ĭ�R��0/��@DUUUݻw�?*q�O'O��-��O�����ٳ|���q���I�&�\�r�ʕVVV*Y*66��lmm��cǎ�/���2dș3g�]�֣G�>m۶��"�ӧ�{���,_�����\r���IKK��/�Sڷo�w��ݻwϛ7�U�VӦM�ݻw������u4��PS���:�]�<==.\�f���w��.,//����1c�����͛�ٳg���������ڵ��ؐ{9w������+++�鬡��mhhnn��>������]�v�۷/����2dȐS�N 6��5/���5~��.�?^9`���$%%����hQW@@�w��O?=w�\```�.]��ncc���y�ҥ��<��ح[�ttt��ܔ�u��y]�������-�ڵ��͛�����K�{���<X�E$ ���"���UUUAAAӦM;s��H��LD�}�Yhh��͛�h͚5���˖-#�~�!44��ȋ���]����ЋVIIɢE� ++ży�K3L�2ESSsÆ ��� �#���QQQ�r#�,����Eg� �h�bƌ����O�~鵸����q_���X;� �.]�lݺu�����Ǎ7�s����Q�d�;�|M"�p�(''gǎ���?t�˲#F�8{��H$3f̂tuuG��<������-7)eaaakk�� mmmmkkkjj�rE77�ÇӋ�5#j���Z�reZZڗ_~��������V�\�t�ү��z�ڵ\5ye,��ܹ��˫cǎ|�[���C��=% q���|p�� nX=�n7n�HLLtww��&�����с���}233---���0��!7����M��*��?Luu��u�>��kkk{{����w�ygӦM+W�,,,tvv>q�ĨQ�T�:n�f͚�tӽ�~�IKK�v ���7^�tiҤI|�(eLJJ:~���e�/^�r�������={��=�S�N͚5KJJڵk�����"wn���а!�H__���?_�h�{�,Y·_�r�ѣG,�'''GDD���}����ф�"R.@_YY9{�l}}��'�jժ������:::]�ti�m����+h�U ++ ++�~����=���_VV6~�����gg�>y����(55����{���\���䚚n億���<��խ[�LMM]\\^4'$�J�b����H$�š�����*���]���7�<{�lܸq3gά��13o�<�Dr� ��ԝ;w*�R700ؾ}��#G>|��q�q�ȑS�LQ�b� ++XDԯ_�N�:�<yrȐ!���\�}��-[�lժղe����Ϗy��� �utt�m۶w�ޯ���{o���u�Νu�����Z0����g_���d�;v<���y�����Bkkk//����������{�pذas��mѢ�ĉ{�}���<��UVV��ۗ_�nnn�s�N��R���s�������o^�����f������p�B������������y����Lo">>>u���n��ӧ:::&&&u�H���7�e�?njjڐ}�^�U0==�& X�+((P�7������:�������r�\���eeeU��URRR^^nee��sss��(��;}��3g�`v ++���~�D"�X[[�^�LD���ϟ?�����յ���8fgg����q�������fgg+ ++"��ڵ�TqqqJJ���WC&^'`��ի �H�%�M���K�U.ݨ���銈bbb�7x��x;s��t�� �IDATI�������"jy�UXX���������������שS'.cegg[ZZr���<99��ĄC���"�HGGG�PTTTddd�o������������ <�Y�d�����x{{���Q[��ୢ��Ѯ];�D���UgCC�6m�p՝���o߾-�U7���$''���8;;�fff��pr��֭[YYYʅ!�b��V��+��ֿG�H���m�B����L&{Q�Hĥ+"�5��hR())) ++���ͭ�UB�PWW�{b�)//����VQWVVw���XSS��Ҳe˖�Sʠ������Ԣ��J*�fggkkk7o�\�PFFFqqq۶mU��d��� ++�BQRRRTT�<�UXXجY3.�q� ��ݫ���:����닀���o������J�a����E�D���S�L& ++���Tjq?}���FOOO__�?���Q*�sU���251b�������x}nnn�۷����s�� ++G&���ڶi�F"�<�\�+++oo��ݻw��QKK+!!�[J_]]]ZZʿ{تU+�X|���gϞ�SN�}��'X����6���m֬������>W{�cll���`nnndd����\�ZZZ������2������ ++ ++ ++��---�u�fhhx��݄�������.UUU��ӅB�r������kݺuUU��Ǐ�����-���)���nӦ���[ii)�Պza ����QeeeUUU%%%D$�H�R������Fbb"W�!==]�P���hkkJ$�� ++<++���l�eC�TZTT�P(�R��Ǐ���ryQQ��Keeejj������>WS��J��#00���ި'O����s��߿OD;v�DR����rqq���ݻw�r�@ ���{Qm{{�gϞ=|��]�vDTPPPPP�0�⡭��P(��ZZZ|ev ##���4�B�0������GEE� [�������ot�}eY���JSS�5�Tݽ{WSS���A��V9.\�,���x+��MD�f�bYV,�ަO-����������;�X�����Z-[�|����������Vi������Z����x45� ������Aޫ�ǹ%��Z�:Z/� ����)//.,�344��vl����f�W��s�l�����xc���z�{�)2V��`�U��:��������x�\;���ˋ�>r#V�DKKG�7�������--��}����j)�]�������VS���2 ����j������fX����j������f���U^^\VQ�D�����������}���`1j������O�d���`������qn�[���xò�m�a����@�������iܸqX�����ddd������N;v�@����P3,����5C����P3Tr����.Tr���P;Tr���P+Tr����g@����P�ٳg#`����SQQ����:9r���@����������@�P������P����@�P����@�P���������@����������@����������@�����������)*���;������?�;v����)*����b ����:}��X�������₀����fX����j������fX����j������f������]MQ���������L��fРA������]MQ�}�ܹX�����fX����j������fX����j������fX����j������f������]MQɝ?��J�����o�$�����)*��`����������w��MT��Ϥi�6�7��bK�,��"��"W�]PPQ�,���xY\@D-�l�#?٩��P����t_�6�����MR:AJ߯��'L&3'i2�3g��2����X���*#`��������2���ʨ����/*�����J�������;��@�@���P��@e,��������TF���P��@eTr�������TG%w���UQ����l `��������2����X���*#`��������2*����J�������;��������P6����TF���P��@e,��������TF���P���@�E%w����Q���@UTr��(X���*#`��������2����X���*#`����J�������;��������**���� ,��������TF���P��@e,��������TF%w��P~Q���@uTr��P���������X���*#`��������2����X���*��;��(������:*�����J����e��@e,��������TF���P��@e,����Q����_Tr��P����TE%w���������2����X���*#`��������2���ʨ����/*�����J�������;��@�@���P��@e,��������TF���P��@eTr�������TG%w���UQ����l `��������2����X���*#`��������2*����J�������;��������P6����TF���P��@e,��������TF���P���@�E%w����Q���@UTr��(X���*#`��������2����X���*#`����J�������;��������**���� ,��������TF���P��@e,��������TF%w��P~Q���@uTr��P���������X���*#`��������2����X���*��;��(������:*�����J����e��@e,��������TF���P��@e,����Q����_Tr��P����TE%w���������2����X���*#`��������2���ʨ����/*�����J�������;��@�@���P��@e,��������TF���P��ի X���j�?>���@��J��1���@y�~�iѢ���@�E%w���������2����X���*#`��������2���ʨ����/gTr%����;��x�8%�P����_Tr��(X���*#`��������2����X���*#`����J�������;��������**���� ,��������TF���P��@e,�����e�2�NX��6����p���CsR���e��V����]%wm�uu���p��O��MBI�J����쾫�.'_T�����R\E��^3������J�S�����R�`IZ���^K����X�r��Z����(E�r��W�k �������u�ܼ�bS���w[�]�,���o:�z���=p�Ur�]=�� �����*�{�U�\;P�b����̺�*�!�g ���)]��yq!!����R,I�.�����_���r�������vJ׃��%�p�g����Q�1Xr�5�Z����(]�Һs���V�1������䞕�.�й���_��SZ���L�]%w�����;��(��J�^z_!���(����2辬�.��y���j����Q����S�5 ++���_� X�����JS������ҸH�r� 5��� (u�B��rGB���+5���L����M�����7/�����Bi+�!\d�t��d甑���pgTr�ӧOi+�!,��,�����H�J����,�w�j�0��z�������͛��,!�g�H������8u���p!!���B��%\�(����P)`�y�����@��)B�������B�z����8u��PƩ5�UHB䦩�4����L�J� ++7W}��?�"�l���39����!CT�䮐]�]��K� ���{K�J��TrB���f� |��� ��p&gTr�駟T�%�p�7/��4���2K����[�����Kd$��4���2K��%����b�\ ��@�f���}g �@��j����rY����A*,������ �*�!4f�K��$'ԓ���pgTr%��*�ک��ᒕX������[�Wr%��*���B�����WO�����DΨ�.T�%���G�Q��PΩ��N/R���L���2E퀥��7/��L���2E���%n�Wy����e�����`��rM�,o���2�����"Ը��L5,��P��Y�]�s�H;��RG����8�3*�w��U�J� ++�E璕pw ����ԯ���c��\�]!|LYA�T�����N�J�~��ڃ܅:/��%���PF��$7o�F���P~9���S�I��K����=��sNXB}�w$���S�nݜ�ܼ,,��P. 4�)KҺ����X2�����9��SN�BB��PN�_�]��%���IN(,���"gTr�1c���܅��C��t ����ԯ�s�N�+�+, �����_�Z���DΨ�a��\E(�p��S)7 ++���#�,W�H�R��(���$�N�㤅���Ϝ�tz9�����p?s�)B���-��@��Ā%ү;k�����1�,!����v͉����/9����M�~��>c��w�:���grF%wQ��T;��n��%\>�����~%wQ�,�+�!d��Β�P�R4�����Q�]8w��KN���(w��$7/9�A�����qf����ˑ�s�� ++�����3����H厄���|qn�nz9�����',��,��P�89`����� ++�����+�!4��q>�9&���J��UrBX�<�ى%\���=�~%�>}�8������^�?@�徭���N�J�N�%���+�^u�Z�������sz�nTj��������|�����#c����Ʃ����dc�^�,c�|��������ETzTS���Pc����ۅ{Ő)ܽ��F�����c��w��qRP 9+I6�KU�h~B����b��3�!9�/��,��ے�쵔�|��{H��_N�[�,�}%����&'����3$}�T����TS��pW�zN��r�9�~xF��3��H)��T�)�{ �=���>�������[��|C��u�"0\2��Y���eb�l���To)����5w��T�Nv��tNN<+N�I煛�иH!�D�ZRP���\=��&�^(Y�rss�v�����F/����/����������������l;���#���� r�yw̴�����TyLTm�y����wtu���*r�Dn�0f˒$y� ++w_��#�}��ON����U�z ++sR�3r�iK�q)�lʖ����S�|4����^ ++|X�ɗ�Z�m�7����H)��T���PK� ++��JNN8)��/�3�$�P�� R������*�V�|+QW3�����rZ�ZO�����T�h~ٔrْxVN<#��S. ++YH���C�|�Ju����M�Ӯ��-yYR�M��W ++��*֑�#Ep���O���./������q�,�E=���c7%+;�j�ڏ43�jjD�a�٣�<S�W/������I6�y9R�A��y9"?W�ϕ�s�a�y�"/K6f��l��#t�.�yʮ��M/�{ 7�кKn���Cr�Zw��)\=$7O��K$��c�ȗ���'�o���#<%}����C��}S3��D���<����T��@d'��O�i��d�}S䤈�aH�!��6��I�>r^�0��Q��"?W����K�|�����+<��G���'����>��^H!i�F+4.B�"4ZI�"+S$�d3]H![��,d��-B6�����b�Y�e![d��q�[����$偐4��Vz�)�����t��6$��쭿mn�0fC���.�"7]R�4��&�1S2E~��\���r�Ua2 ++7��yK�>��GxO��_x� w��O��J���W�� !e5�|��)�,�"I���<��ߖ��E�I�tN��I�����2]=��7eC��͐�s�웲$KA�R�G� ++�E�ڒ��l1KB.�37˲,d��� ��H��in}��F��wQ��$��h��I!idIs� ��a���Xd����$ �鿟�-��1Z�ȒV�[�.�k�q�4.B���)ҭ ++���q�d�%&a1���( 0)���B��IXLB��M!i����M�$�P��.Z��.���/�A !$���I�o�ZXL��,�&a1I�Y��ӭOLyl���~/�m����vK��7\��l�d�0���|aΗd��@��o�ݜ/����$YL��rq�4Z�⪬N�h�)�F+4��2��U����˗�w_��_� ++w�Ð�E�M��"��j�4�O���[_EI#$��磑$�[�@�F�"�������o��"d�l��Y̒�tY6�����tHB#$!�t� $YX7,!�[G�F�����X�?�摄�n�q�e�YX̒����@���Bs�{���om]�o���[y���G%��O�)������+�y�:��Whuw���eC�dȔM��*� R��R�Z�z�n���G-IB�"I���B���������۟���",&e�� �B�m��ҭORH�e!!IY�{ Y���ʲ�X�>ܚh��ձ����5(?vI���E�6_6��E�.ݞ~k�&[�7"���Z ++�vɲl��F�����'J�����3��W�U�����v E۲eK�����Y9�n��V5���j�$o/9��f����0;8� M� ++�8g6J�:��xK���^8����M���X�[b.�?������f�x���D.�)�����|M��CG���B�D�_݂r%���hK���W5;ze�Eh4�r����/9���35~ޖ4����I��+�88�Ih���xK��]�:8s������U�9ޒ<�sFgΖ����K��)Q�KԒ�n|d���^�h�<-�~�����z�7>���������j�G/����z[=M���`�Zb�Z�_��xzȅ�B���]ҟ���,���*W ++/��XB�k�/�g$�����w��������<�1/��7��t%J�"""�&` !���3����Jp@��p���<����ܖ�4+((�.�������+�����:��(w,�\tX���Af6�SSS/\�p��UeJZZ���Ԍu7��322]\\*V���Q��c��{/)))--M��{yݪPm0������gϞUƔ���ܳ��+%%%:::///==�رc���V���(�3gΜ={6???==��ѣJ~2���ѩ��&��������B�^^�N!DDDDHHHNN��˗�+��F�ɓ'�fG�L�H�{�bbb*V�)��c�bcc###��2���;)))��� 6���Bdff*��]�v��ť~���F��]�t)((H�$���l!��drqqIKKKLLT��t:]NNN\\\ժUUog�VNNNVVVX�r�)88�ʕ+,��po\�v-00PIWB�7n���j4!Dppplllff�͛7�\�UI����B������U�V�t�R�*U ++��U)����hB���+����0����%(���p�rrr���RRR.^����S҈5�(�Fc�ʕ�4iR�R%!��?��c�eff*�W��� �ɔ���z;K����Z��~/�D�����X,F�1..��ŋf�9666::Z�e���`>quuuww�q�"&&&;;�d2Z(IRDDDij��d��[/kT(����ڵkk4����cǎ%''+�R����xebppp\\\�&M\]]��:{��$IJ��Jփ���&���4�L։���N�`���V�Z)rrr\]]%I��':��`0���T�^]Q�Z��U�*�$I��t���III=��S�Z���z���KFF�����t���p6__���t�,˲,+=�����5�^��v횿�����B��ZO���֫W�ԩS�+W��WWɲ�R\�ʕ+���III7nܨ\��3���PP�*U�������)%6���&''߸q###����!!!����*U����[�,����������5j�pR;K\+,,L��%I�C=T�Bg4��� //�ڵk�={� nnn�k�Vz����srrΝ;g�X��u���� �IDATI��W�ɲ���������h6����*V��F.^�XR��J)�Z���|�F��v����0�nnnv��,��l��.����:r�HӦMO�:�����o���\Z��h�2`��� �,�L&WWWY�/(Z��U�Z5Ƨ���$IJ���ڋ2b�����y�����X���*#`��������2���ʨ���`�4u�$I���@M;v����^iz��l�B����X���*#`��������2���ʴ�<W�������=X���*#`��������2����X���*#`��������2���ʊ+4j'''�y������|Y�������(Gԭ��P�"Z�����,����vԊYw>EH����Z��1X���*�C��� ++���+��z����TF���P��@e,�������h�,KQOi4���~��ד'O�3�v�,˲,�q-v���\�vm���-[��ѣ�gNHHPjn/((���C��(/J�RSS�~�颞����n�q���^{-$$�ܹs+V��X_~��?�p�mܸ144�4MPNT�T)11��/�l۶����3��g��W�v튚!66�СC�-jР��-� +U����������Ǎ���o7j��ԩS3f����jԨ���w�̙����^z���̞=����_~�e˖-�i佑��3w�\!��ѣm�_�x�_~���0`�N�;���5k��ûu�̠L���o�������k7n����w��=,,�vznn��͛������Y�V��{�Q�FvM�~��ڵkO�:u�ڵ���'�x�C�:�.>>��,��6Oq�ĉM�6�<y2;;;,,�M�6�۷wuu�}ɮ]�:T�V�^x�nis������������^�-ˮ]�v��y��YWW�Z�j�o߾Y�fv�}������v�S���ٳg�L�&M�<��S։���{tt��Ç����իץK��+Z_�|��zyy=��� 6�j���P֫<�Z�jhh�#�<b���~:�.00044�Y�fz��v�������=z�h4>��#/��b�ڵmg8p���M�N�>���_�~�=z����_��}�����3??���G�9q�D͚57nܱcG�g�T�Vkm����p�,�s����͵�̭��o߾�*U������`��N7t�PWT�͛7���*��o �:u���ꫯ��}��:t�4��[111�֭;z���b�S�N�Νkժe;Cll�]��?~��Ո��v�ڵj��n�w�ڵիW�<y��ݽ^�zݺu�き�`0|��W&����W���|�MQ���իjժ��qWh��wwwoԨѽ�KD����k�ƍ�\�"����hܸ�rưV�Z���s|9�=�XQ��8P��3���QQQ�VJJ�{���?�t:!DZZZTTT�N��A�"��Y�f۶mm���S�c�g�N�0����z��y�湹�����ʕ+_����z˚{���;l�0��ҪU��u�:th]�W���O\\\>l]�իW�Fchh�5X�����O?͞=[ѰaÈ���{��رc˖-cǎ�P��u!111QQQ��A�U�T�m��͛�_�>dȐ�>�����ӧoڴ��ͭe˖�aݺuk֬�ׯߛo�i�����{��Q�:�}aN�:��Ơ� eg���8a}��=��cO=�TRR����/^�t��5j�~��������,y3666//���>}�5�*�[������͛SSS��?���Q�~��߁f͚ɲ����������駟*�2�s��]�tiXXؓO>)IҚ5kV�X����cǎB����w�}���aaa�<�Ljj� ���~����peE�e���B��m$���������ۼy�6mڜ?~������4i�$I֦>��3B������=66���m�ԩO>�dQ,[111���"::�M�6�$�>�|h]�v�{��h��� ++ ++ ++R%`)F��H��+Wf͚Up�͛7�/_^ԫ._�\�����;w~�ᇞ��ʡצM�V�X1y���{N�aݺu�&M���O?�tdd�]�� ֣G�1c�X���у ++�ܹsnn�ҥK�-[�t�R�C٢�����v���W��L&�ݓ�l6_�t��ͭO�>։�� ++�-|HHȣ�>�l�/\������W_U�V����v�b0ƍw�ʕ�S�֩S��Ϙ1�y��^^^��s����_~Y��N�4�]�v�aDvv�r`�tIIIy���===-Z��Y����?s�Lww�ʕ+�X�º�aÆ�{���3�,Xмy�O?�T�A1�L?��ӬY��x�e˖��;Z,����zҤI}@B(1bDtt����:x�`��+33s��ɋ/NKK?~��Krss>��O�Nܵk��l>>>���_}����۲e��ÇϜ9sy�s�n�z �c���}��q�ƍ1b�ҥ��O>��F��,���lݺu���={����l;��#0��r���#G�=z�ҥ5k���t�����^��?_]�u���'��n������իQQQ���K/��ly���O�2e���FZ,��u����W_�ݻw�ر�(�k*U��Š�ӧ+dY>q��;�3bĈ_�Ց��o�>�y;v숉���g���6mZ�F �Ųv������-[*�6eYys�Z��W�.����}y```��Z�����:���?&;;{����۷3f����ݻw�=>��&M� ++!�{#Gz{{!��ޕ+Wv�СaÆB��2v���(��mڴ�֭�w�}7v���p�ܹ9s��t:��h�`�{R�ٳ��w��裏��%w���͛[������6m?~����������J�&N������<!Ą �M����+�1b�N��ӧ��ف�t�ԩ�����Y��SdY�5k־}�����q��;*G���zQ���3gZ,��3g�h��:]�9�l6[?óg�fgg۞[�$���oڴ�]�n1�\��p��ʕ+����"�Vۯ_�����[��W�^�E�.]�4i��Zv����/6��~oo�O?��ƍ�֭�ۣ֭�>j�?000??�֭��h4�Y�������Ntww�>}���J��ٿ��hT:rww���>�nݺ���+[�$���;<<��7ߜ>}���ow��J��:t��|����5k ++!�z�-�VU�\�y��w�z�j�:u���V�^�lݬ�;|�pjj��-���A����V�ZٞK-x��}իW�G��-:s���,��ׯ�G���cǎ}���#�bŊ}�����R��w�}7i�$�51���۶m���G�ٵkW�>}�T�\�v M�6MHHX�jU1k�ݻ��gN�2A��ϙ3����GBBB�u�hѢ���+��V�Z�l�Һ���t�۷�믿���7n���u���� kذ��ݻ?��b�K~~��ɓCBB^z�9s��ά���S��j����W�8�+,�����_\�dɥK����=��T�cǎ-Z�8z���?�<`��J�*�;wn����{��^�z�*U�_�^�ڷo_p�PA~~~�i罷lٲ�˗w��q����ߴi��������]�v=�P���ٳ��?�l��K�J�$�̮�`����fs<] !���,K������ҥ˂�Ν۩S'�g�u�v���3f,^�ؑ3��E9�ثW/���V��۷�ѣG-Z4c��t��гg�ŋ���{���ǎKKK�ի���{�e*�I^^^E�!+��իW,��M�>��S�v����ߋ���9�����*!DFF����m�R�T�ҥK����l�ݨ,[{��B�+S� �\�{� ���:��G���[�~�+�������4hРA����3g.]�t :tB�]�6..���ӦM[�v�)Sv��1~����{Oyabb�2�*00��/��ӧO�>������S��W�! @���b�b��Vn c��W�;7nܰ�'??����^�:::z���ʈ�b���ϱ��_|�u��� ++���qG6t�T��ոqc!����j�t���}||�ϟߤI�|��#�<��#��� ���{�N�:�V�Zcƌq0����8p۶m�~��ĉ�G9#�����q7V�V�����{�~����z�*j|[�;&�hڴi��*U�ԬY�����ruu}���?���M�6u������y�f|||HHH���۵�~��b�iegg?���-ڿ��+Bl߾=((����dYVF;���kw��+ۗ����g�Сî]�Ξ=[|�JOOB�u�X:t�رc͛7/j@��l���BX�4(���#:::))) ,,�vT�_�%�P:�,��`p�;�����o��t�bb���m|��\]];t�u� ���;�Pu�4iRbb���X����8q��biӦM�:u�u�V�~�ѣG���+3f�P�]VVVQg�D��L9,� ?11qŊ^^^͛7W��m�v���{��mٲ�"))��ɓ,f?u���3f<��S�ڵ��矋i�rML�֭m�-�� ++u�̙�Ǐ7i���&(��kmܸ�W�^v�I)Z�n}��������F�*麺t�Ҿ}��l�r��E孥��;����͍���ݻwTTT�Ν�la���Ӣ�CV>>>ӦM6l9sV�Z��믷m۶D��F��ܹs�@o�UժU8���`��Fcǎ�-[6s��'�xB9*FBB����������OFFFJJJPP�uzdddժU7lؠ����_����_/��6��{��INN}�������k;L�P���kuss�B^�҇t�ҥb����_�r��nݺ�ӣ���^��f͚-ZL�0���w������M�ZG�)kѢE�-RF0�����{�K�.��V�����/�ܸqcbbbxx�����~�i�Oi�ƍB������f��N7w��;��,˺u�|||�עE����}���Snܸ�.��������ə7o^�J��Ν��Μ93jԨ ���_����>Z�F���=z�ڵ 4�$),,l���������wdE:��U�V*����}�������]�r�ԩS111?��s@@��3l7}�Qrr�!Cz�����/ϛ7�V�Z�lf�f�i�\]]G�u�c����d2�]6�������7ʲ���}�ҥիW7h�` ��ǽT����G��ׯ_�3������_�xQq��%�,�Vk�Z�y�慆���ݻ��98��5bĈ��ܖ-[�ݻw�ʕ����#�R.��߿�ڵkgΜ�hѢ��T醵�f��ԩS��i��z�m�z��/_�r��%K���?��6mڻ�ۣG���ٹy�B�]�J��V�6 >|���?���/KJJE�N$I�^����Ǔ��m�F����3�_�z������'�|��=w~~��aÔǏ?���/�X���~����?���~���w��R2��+�l������z��3g�����v���~ؽ{�"$$��W_-*�ʲ�p�B!D����###_}��ƍ7m������ٳ�Ǐ���O+V����'&& ++!�R�n����[,��K��9r�ĉ�q ++����Z�R�T�ܹs111����a֯__�ծ[��o߾v[LG�ܕ�����ٳ�z�Ғ}���1�N�:3f�pww�2e���Ǎ�������̙:��v����>r�Ȏ;Z�T��̜;w�O>i���駟Xx�_�>99y�����������7u�T��{�gw���4ir�ԩ�+W*��/�[��M�6�ٳg�ĉwܡ[,���(???��=%� ++!���/�SߪF��a���*`mٲ�`0̙3Ǻ�����ڵ���˷m�6b�I�dY�裏<<<"""�k<<<� W9�ѹs�;v-� W�^;v��>ۭ[�y��=��E�*(88xذa�'O����:u�d7����7111++�:�ҥK6lBddddeeEFF�~�����~��_~y�֭_��_|�u��I�&��kK9Em4 C����4Sh��f͚�m���~�رcDDD1����b{�ߎr���o��'��1cƞ={z��e˖�����ȃ\�N�۱cGFF�ŋ���ݻ�V���mڴ�ݻ�#~*��B���+�ZmÆ g͚e;PT1q�Ĵ���������[={�=zt��ܺuk���m����� >���ڵk��X�`��������z��a�Ӫ_������/���m۶�P�D��b��ʺr���ŋ� ���+����6��֙�V��t�)c��������g�����Ν;gw�wɒ%v���e�JC�����������{��ƌ�|��ˎƍw���(�d-���� �-����i�9�����9s�xyy�٥K�6mڤ���{ʔ)������ӕ|c2�>�쳝;w~������k]�`��q�f̘Q������?�����R��/66����:t���tWةS'�*B�ɔ�����Ϟ={����~��#C�K�T�_�~ݻwW.�TDFF�7�>X�t����%I�R�ʞ={�Y�r_�re��V�BCC�80�>�ꫯv��U��#F|���~����~���;u�|�r���YתU��?�Z�Rѿ�c�_~��� ++]���_Ϟ=۵k7oU�VM�2Ŷ�dQ���*W����Vh9���8QD��$I�������̙3{��b*�)K����Vnnnrr�V�-8��Z�j�=�����۶m�m۶�����fI��W�y�A�}��'�>��m���>;r�H!�����������ߢ�vD)���j}}}��������]�J�܊+5jdw<66v̘1~~~cǎ-�/]�����҉o[A��˫m۶�W�NHH(�34���ϣ�>:q��ӧOϚ5�C�AAA�F����͜9�M�6f�yݺuB��C�Z?+�n3{��Xv��w7"���СCS�N�t�R�^�^{����<k��t�:q�� 6t�w���vLNN�z���X�l9%%�:E����`�/P���;6++��/�,8B��ݽR�J�*UR.s3f����?��!Ď;֯_?w�\e���o�j�jРAo��֚5k ++V���/���+V�h�nW�z�����Ƿh����_99`W�T���P��jZ�n]�bŞ={N�>��`�W����h��ܶm�f7]��n۶�n�ЦM������t*~��GŬh]e�B�!C�({�g�}vŊ���k�Ν�����#F�2d��ի�V�&Mv��q�ȑbnOT??��C��Z�j�������(��Ջ��;}�t�����y��a3��N��� �`��Çs}{pp�N��r�J|||����[�n�W�����ƍ[�h��u��w|;B�^߾}�ӧO���_�����g��{��U�hi�$�k�nŊ���� X���F�JMM��o�� ����볳� �N�S:Ւ��l�BJ�MMM-�#G���Ѹq�_��ڵkAAAk֬���F9�<{�llll�f�l[k0�N��f͚�^{�D��F^^ޞ={�,Yb��_�lٲe� ++�900p����V��ܹ�{�g��P��5%+]������Y�כL&g� �e�X�M�v���w�y��Re$����G����y�f�Vk{ ++�^�z}��]�p�#G ++^����f�T�֭[����/<<�6`)��<�-ͮP��jO�>�����!���r7�ֳ�V�Fjڴiv��?��]��j���Yɲ�ԅ*+�JؔA�j�Æ {���fΜYL���Z�hѦM�����ݾ�]�v�~���e��X`�l6����=xzzzxx���sn[ݻw���ߖ.]Z�H��;������[����_^�j��_]̕�����5kֆ d��r����*�E��f�ҥ�?�xQ�C��B�����lٲ����� ++�J��m�222ƌ��*xˠ��������U���N�_��O?�t��i�,�\���P�p��-{�tH�����+�K:s�#gWUa6����<==�͛�}��5k����/g3�L/��R˖-�}��_�5;;���<==�����������NB�iӦ� ++�@e6��͛�f͚�ݻ1\��Jܮq������nד�lv ++���t~�Z�t�_|1iҤ��N X�W�%--�d2U�\��wp���;����V���ݺu���C�V-�� �IDAT�)ww�Тy{{'&&:�,��ԯ_�s��'O������$IC�1���f+���{�b�|��v�/���V���0`������ù���5*f���F��k���ѣ�|�������/��B��}~~~#F�8v�X��[�n!!!������߭eY^�r� 6lX�U��U��~�ضm۬Y�lk��]ddd1Mr�ɓ'�}�]!Ĉ#JT�����#F����B�ܹSag���2t��?��s�ر/����rrrƎk{K�z�j!Ŀ��/�O<�D�*U�����+LMMݶm[DDD1K���~��ĉ�j�*�o�l6�]�VQ�W���,~<��<<<�̙��W_�h�B9� +�2PPP���m�ڔ����)�*'�mխ[W�<0���M��hѢΝ;�=��\ANN����m���W�n�Z��I�&YYYǏ��G�Q���>����amll��`��w�����W����s��וܝM9ITh͂��7�شi�̙3[�n���/�������W��j߾}\\��_ݧO�:ԬYS�ќ<yr���>>>J��X,*T�|���/�ܵk� h4�s��-]�T��}�ᇎ7~�ȑ������?~�x�֭}||N�8�z�j//��ӧS����+V�8q��y�����������:ujذa~~����w��Y�n� &s��_�~�7V�����]�dɉ'z��Q�b�����˗�>}�o߾O�;b�ƍ������N�:z��^�����H�~[���z��W�������kU�V5h�@�G���C�=s�Ldd��!����h4���?v��+�����שSG����+�ԩc�LD�Ӎ5jذa�ƍ{饗\\\�ϟo4?����S� f�XRRR<x��� ++*L�>��!_�N����ꩧ ++~�{�1e�p�֟*����#���c��P"��Ç^�ڿN����h�4i����=<<�����g���.]�����~����߿Q�F...'O���o����~�me�>}�lݺUـשS'??�Ν�V��ԩ�R������ى~���]Ŋa2��ZمV�rdWh�l�љ[�l���mݺ���K�����o3226o�\�Sʰ�+V���С�#c�dYV�(�=XB�J�*���;3g�������;�¾}��Y��n+��j�x㍦M�Ξ=�::/((�gϞT�F��ڵk�F��ϟ�j�*���~���%��epp�Y��.]�x�bk���m�>ܑm���Æ �c-{�zs��Y�~����:����,��xDDD1�-_��G}��o��f�����?�����)����U�6x��^x�.z�����z�ԩ�!�F�4hP��������9sFq�ܹ�?����:�n������?������`��pM��0�_�~��ݭ[�^�`��I���[�j�.\X�\���h��ëW�>q�ħ�~�����?�B:��Z�j����Ν;u�T�����;v�X�������K�.�-7o�ܽ{w����n�pp�"p����U�����_|�ݳm۶ [�p�E�����7Bm߾��o�iݏ���|����-������G��ܹ������������w��gG���(�Gv�V'N�P��u:]ddd�F�ƌS���5��j�J]�B%$$�(1X͝;��Q�Ǐ5jTpp���gFF�ٳg�t������Zx)))iii>>>���E%�����UHHHi.�2�IIIyyy����;����JNN�h4���*�OIIIOO�������l��eee���h4���Gn+T��hLNN6�L�*U*f �<*T����) e�����ɓ'�X����/�r||��RmŎ;�KGKD��9X�x`�ƛ7o���ڟ$�0���nnn���v����l��켻y:�+�;���e˖�X�`2�6m�d4�b���6k�잝n�p�(i�ڶm[LL�o�Q�)�Ųjժ�+�� \�����у�Z��Q���*}�*�U�����C���P��@e,��������TF���P�JLq�4�{O)��@�E����X���*#`��������2����X���*#`��������2����J�����zv��ѓ&M*�* ++�z.Ԋ+�~�����-p�ʕ������*u���=�.]*f�R� �Żír�hʔ)�ꫯjԨQ��3g�T�P���={�L�:��/\����FEE�۷oʔ)z���7n�رc��bq����o߾M�6��ٳD/P�S�N�1b���5k�t�*�m۶m۶��g�i߾���ku�֭o߾������;o���{� *^i��o�}�ԩ^�z���u�����kҤ��Y��p������[�;vL��T�R�w���Ǐ�g�}�Y!D||��ٳ{����C}��wW������>��CB�ڵkO�:u�С�f�������l�<y�b�ر���։� R�;����v�7B��?�|���vO���O�0���p������_��ۗ��Ӳe��ݻ���[�=w��ʕ+#""���;w����?###{��!�ؾ}�������֯_�v�ڒ$��}��eff���;�m !DBBºu�v����{Ǚ���֬YS�v�O��������o�MII�0a���K�b(�f�;�9r��!??�� v�R�Jʳ�7o>r�H�/�Z�j߾}E����R�J���0`����l����m�F�`��Q>�jժ�?�nݺ]�tB�;wn���͛7�]��СCϞ=������)�JMM�|�r�����U�~������O>�<y���ƍ/^�Y�����ubŊ��/_�|� �ڽ��{���pW� �����~���w��ݻwoOOυn۶���� ++ ++ ++RfHIIY�dI�n�l�n�����n����~�me�ŋ�,YR�V��U�Z,��'O�:u�`0<��SӧO���[�,�6lx���*���W�Z�������[o���/:[LL̚5k ++}���m̘13g��߿�kd!nܸ��G���͚5{�g�Ν��w߭\�222Ro��III)))��`T$Y qqq۶m+8��^8p`�/��ʊ���7o��ϳg�FFFnذA�唔����u��Yg^�|ydddBB��V�^ݢE�����-��/�������*������/�`���~۾}{��h�r�������۷��%�e��ŋ��,Y��99i�$��1�1c�S�]�֪U�F�]�p�:�o����\�z�uJFF�g�}���\��˗###���sw����*�'l�dɒ���+W�Ȳ�m۶���ݻw5�K�"##-ZT�&����ߏ��<t�#�d�r.''gȐ!�?��۷GFF0���������;v���P�ܟ���ۼy�:�.44444T1q��C�Y�_�x�ʕ+�:uR�i2�^x���[gزeK||�"--�:��߿f͚�����ǎ����]i�Ν�x�����ׯO�2�:�̙3B��#GZ��CCC���� &�Iq������k���)O)S�_�~��5!�^��=�����K�, �С�2�Q�FO>���?�<x�`k�����aÆ%&&~����w�{{{0��ۻ�x(����C�W&�T��'�BKRHHQTn�UIJ�6�[��� ++�G²T*$��]Y*��E~.�5�����ܞ�ܙ���mS�����<Ϝy����s��w�� ooo�^���"�Ɲ����koo9r�{��>������1��~NNNii������rrrdee���J���ؤ��$&&r� M�� 2��ɓ�Ͼ��B�����`HJJ��ҥK��� �=��� ��Xuuuyyy������t���ŬY�^�����ﯪ��](''��������.���'56�����`� ++��<������#�Fvv��5kf̘�"���f� ��ԩS������m۶����H�w��<<<�^J�������Z�g����֭[%%%���<׳X,__߲�2___CC��֏P&�ɟq��uKKK���͛7aaa)))GVV���r���<��G���##����>\\\\�����3f��"���˳���j$A�ϳ�`0B����O>�d�]]]�� �&h``���$$$�w+5hii��t===�<�|==�G����mڴi�ԩ��� ++E__����3g�D�������|ʔ)111Æ ���mkk#���r�$� 6����fff�����ׯ���� >)))<� �@EEE��N����)(( ����"77�'N�����"�穥�!�U��榦&��O�>}�ʕ�+W:::~H����!��������O�8�Ɩ-[���8���^]]}��:��ݙ-������B[[����t%l6����4MCC#((h�ܹ_�� @ � RRRB�ׯ������;;;��a�6A}|�5}����,�Paa���3Y.!!a``���cddd``����z�j�PAA���#~�{��'"�<x`ddTTT��b��x�ͳg�JJJ�4�������B�Jl6��r&�)%%E��-sذad�<n�:�h��?`��C��+##�ԩS�����f唔�P�T������8::r?��e!|XUUUZZ�t�R{{{\naa!p��=}���biii SIUUU}}��+/^��蘜�̟��� ����[�n555egg�[���M@������ijj�ۑu$����o����m۶������?y���B �����ݻw���PCCw�ĉǎ���5gΜ.���7������hzz:��O//////�{�����o����ɹ_�t�����;>lnn�.�}�vzz��Q����.]�doo?s�L� ++SRR�*&%%�������=]!t��-EEE�2�Pccc__�!������!�����o��wͼy�$33!dii����p��'N,\�PYY��2h������Gv͙3��Ύ|U�VPP������!�sk�7A�8�244ljjrpp��� ++ �k�� �����;w� �:::�˩T�+�ϟ_QQ��@�OYY�A������!:�N�|���loo�n4��ͧM��_���SD��y^l�!O�{cc#�Fóz�-[�����J�uUFkk믿���뛔����D�A���z���������;88$''�\�������D�����mhhHNN�^�^�zI�ӵ��B��������������uh���LJJ��_moo��ill�E�mmmy.+((@M�:U`%�� H���a�XVVV��ꩩ�===�^�B���s� 2��lkk��7���xRJMMM>�k�Ç�g�r��h8�������Ɋ��������������������캺�y����Ԑ��6��������N<X �`�G�yv_��<srB�����[�bEbbbFF���]5KJJ��t;;;111����-[��S���������Bٿ��"""<<<������,--��~��ҋ�����ɥ�����p8���x\OSS���>55��Ύh�4A�k�g{��˫��8;;���hii�;��� ���|���y僺 H�V]]^�KKK����p�X<�L&�B�R����FFF���>>>[ׯ_���������?u���ӧccc7l����i�&� ���!���x���s�α����z:��3i������y֬Y��ѐa ++)�@%�n�81�'��|x]]]���MLL���ɓѻ:�Ν;�Ǐ'��1*�����EDD|���<�����? ����@EE���ǔ���ʘ�]]]�>]\\RSS�9�!��4A����,\���Ç�����yS[[;u�����i40QXMMMaaa�惕��{��Y�j��ŋ��\��溻����_�~��+�ܹ�ڵkjjj===o߾E�y���EEEEEE�����ۇ��"����v�ء��������+???\��ׯB��ʖ��NNN���wtt\�|���+y�������+((�� ^��ҹ��ܓ��JS�Lᾒ{O=%%�;v:t��ٳ�IE��E]]�X�˗/�Z�J`�*�B�={������mbb�֭[�\�����8ku����x�=2!�Ǜ7o6oތڹs'w�3n�877����r�i�� _-� xv|ȳ�˗/Bxyw�i40�X�/_NJJ:t���������Y�x�c�֭[7w�\���~�-11!��u���Z[[+))r��}55���7$�w{{{�m����q��y�LR�����СC��û��p�V]]���RDikk?~|ǎMMM������UUU�~������o<��AJVV����̙3eee8�����YYY/��lٲ.DFF����&���x���ٳq��Ǐ�C������ISSJII���>��zݟ��7��q����%$$����x���s������~~~���\]]�ݻw��Q%%��F!� _������2�����ڵk!�y��Z��^�`i�&�������sqq��Է���ݻ���066vҤIFFF7n\�f�����$))9l�0�q�Ʃ�������Zkkk]]]�����?���n۶���������;::��̋ ����ӧO#�Μ9�}���S� ++\�!dbbbhhH�����h4��)�p�B�����ի���iii���ǎ�������!##������SJJ*""�B�����������=+w��e��Atww�z������ܺu+��TXX8|�p�ס�����77��3g������[[[0f��h4�����ɼu떡�!�ܥ��:__ߒ�www�k�HJJ:t��������۷����h��@�|�2::������q��ѭ�� >\�nO#�����Mٱ�� L������հ������X,Vnn��lvLL�2sqq�>}���gyy��c��t���Ny�,+""��ɓ�/ްa�J=~���ի�/_~�� mm����cǎ�������f͊��wqq����?��1c�bmmmee�����d2���}���aee�`0RRRlmmqc�������O�>x���b�}��������Ξ6m���ꇤ��RQQ������ٺu+Bh�ĉ111<����ݺu������������455�/_ncc����%�ʕ+��E���TQQ����%�֭�K��knn�R�RRR ++�ƍ���䟀q8��W��۷���{�ƍnnn�������q�F??����#G���lh��@mذaڴi�N�"����mllx(������<�� L/%��:;;�������̙���sww��O�._�|˖-<uuu�7o���MMM�_�"noo������m�F�;z������СC���jjjlmm��G<�� ���������4�i!�����s粳��nݚ��@��\\\���Bt:������P[[[FF���������������{.��`����d2���#���33���H###��A����}�vԨQ<Ks�Ù��iJ||����C���h����^�jB( �g��@��ջw�?~�����'O� �[KKK{{�СC>�6�� ^vv��B���� ++�p8����~�-�nƣ�����l��������333��������������ߞ����Ǐy�wBA���twwwwws8*�*...!!!!!A��$%%) ++����q��Meee:�.�c� ���֗/_���hjj����GJJʾ}��+|���VGGGuu5^W]FFf ��kjjh4�N��:Fcc#�]�&�ϐ� �&��������eee�����J����a$���l����:����������>�&z�������j��ِ5 ���� b`�����X�����"�������gaww����� ����w�����'�b�Ѓ���� b`�����X�����"������A����� b`�����X�����"������A����� b� ��?�W^������q�ѣG,q��� ++�IDAT��+Ap��S����SRRDr���O������������g��Q__�����o�����h���R|���ݾ}����&L �u���M�6 �PMM��ŋ���;v�@������.[�L���TVVv���?���۷����w��b���}k��0�� ����AAAnnn�ƍ۰a�ً/q��ѣ��BHCC#**���0***00P^^>##�ҥKaaaC�EUUU]�t X�����|��ɒ%K455�{qeeeZZ����������F����.�,B�B���KBH__�ʕ��b����,�͛7>>>���<_9r�ȑ#���BӦMSRR*--E���HII��������ܹs�K���8�ʕ+�o߾���FΘ1�� ++cbbbbb���ϗ���n��%T�~��U���fS�Ԍ��PCCëW�-ZD^�?������ ���O��͛L&�'���_���cIIIII�}��Q�T��U ++��*��={���wIYY�O?���p8---���cƌ�@NN!�b�/^����D9;;������#��.]*&&���/̍�>ZmmmCCy����f���w�DFF��+<�^����Ǐ���Ϝ9s�Ν,�����`BX:::܇w�v횩�iyy����N���Y�f������"�� ++'W���{yyQ(�������-[��h4eeean��ъ��Ξ=K666"�|}}ɒٳg�GT��l��3gB˖-SWW�>}zPPД)S��|=D��U__����b� ++��'O{7<<��ٳk]�|�����B����2�̀��ٳg/X��!TSS���mbb����������CWWW&��}��۷��:A���?�����B������۴iSxx89����lB�����y����{����w��)))�ߪ)}}�s��\�v���&>>�����z~~~ss������7oޜ��#���>����={�DDD̛7////$$���CYY944���m͚5���l6��M���� Ճt������GDD̘1�Lbutt$���������매��<yRII �W�ݻwy��Ƃ�L\���������ttt6L�[�|������P�������xyy�C[[�9s�����.77722rȐ!���999����9z��I�~��#G��ڵKOO���NWWW^^���I���i `m߾}͚5<y�����cǎ���'�������͛7z�h��Ŋ�����w/����Z[[M�4 �P444<xPFF���p�ҥ��*���1���\ww����[YY�����\�d2����dddV�^moo?r�H����������ۃ������t�ѣGoܸ����k�.uu����2�S�m���I`�������"������1y�d���Wqq���ƽhւLLL����,X������ތ3�����ׯ_�LBBb������ZZZ���d��+W�^�����3�T������QMM �F�� ++��*�ڽ{wvv��S��������:::8[VZZ�͛7eee�g�~����<�W222����{���655���8::���/������:::QQQ��� ��?��"���}Ĉ����'T����`aa�]���w�����>�������;�n�/�uuuG��>KB�?��O�ԩS!������^`�Zן���.Y�����{�ѣG����]����;44TVVVLLlѢE{��Y�lw���|y� ++����� �8w�\gg�]�F��k/^�]�VLLL��g̘��S�b��������즳��RPP���Sa~~��Q������ѣG���>|�P__?33s�̙���aaagΜ�e���/�h��B577������[[[/Y�DBB���:44�������`9r$�VW�USSs�ʕ͛7��3mڴ���aÆ���������t��ኊ�I�&�����3"T�EDSSӳg�~�嗴�4 OO�+V�FvӦM�&Mڷo������������ƨQ��T�g�JJJ�+��<{���CRRo����$&&��(�իW܇.\�P(666��F:���;λ��_�x���5aɓ'#���� ��|����>>�b2�k}��Bh̘1������x�A����+W�����Ⲳ�Brrr�����������8q"��xVAA,��R����Z�����>466;v,N�277���suu������������;x6���/��+�Oww��g������'N����6p:A���O�<��h���g�ŋ���&&&�eYq��������b��������](%%���?�fp��='��>%!۟�ׯ`��_,���K��K���������X� ������H�������%11��XЉ�������Z��$��> �������ȉ�G�O��]Y�������AC�������O������@������@� �����%������=������D z������D,�����у�����@dz{{��� ���������#F@����� ���A@��������t1111ز����@x���JJJbbbЃ���� ������b�@�������z{{�ܹ���D�R�������>Foooee%A�ͻ▕��w�������ILL���������҈#xC+�ŋ��������|��V<�,�.�"�-��J�B�4,����|������8��?�`�Ff������IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/zh_CN/image/4.png b/data/ukui-system-monitor/zh_CN/image/4.png +index 5d8c1ca..2d30d80 100644 +--- a/data/ukui-system-monitor/zh_CN/image/4.png ++++ b/data/ukui-system-monitor/zh_CN/image/4.png +@@ -1,90 +1,169 @@ + �PNG + +-��� IHDR�����������jA���� pHYs�������+�� �IDATx���g@������B�(v����K,Q�/��b�F����(�ѨO��`�=*&h�é�T�I���my^�Y/�moU$�y�ݶ�=������`:����.�Rs�0!�AaBx��� � +-��´k��d�)������ yW 9�i2�6m���7��������4h`�XBB����ٷ.���o+o�iӦ�������~����G�9��I�&]�z��x�ر�u�r.9�p�Ç �0��)))E���yzzV^�Y�f���gΜ�}���Y�����`ժU�7uk�z�>������3g�X��}�v�C��S�O�ޭ[7�Z��_p.3�Zq?�ݻw�����G���O?U����K@@@ݺu��������N�:�5rrr���hԨ3�Z� 5j����N���jԨQ�jaY,�~�a����~��^���@iii�~�v�� ��=�0a¸q�<x��ݸq�͛7m,��)99900p�ʕ�0q�D___f��?�ئM�� >g���`�uXX�4m��z�^�z1/>��#���`� .�\��_~)**���>|����ۭO-?��CAA�z˖-3f��ś6m������(--}��l,ǚI�ן<y��QL&�J��W�3���tΜ9%%%�[��������]VV���R^^�k֬9v�X�~�����cǎ͚5�ݲ��ӡ���ϗ/_���\�p���{���7o�|�С*���q������݃�����k�X��^�x199���s�N�ڵ}||T*M�?��� l/�0]�xQ�՞?�����\� j�̚1c�������I��������ݻwy388��������]�n]77��u뺻�3����������������g�X�.]J��e��f�G��Z�M�]�X,���t'''�prr2�ͥ���ܲ���+W.]�T.�3S�7o������ݪU�K�.�h�⯿��裏֭[G�bp9��͛7�;v������III>>>l �r�ҥK� v�ر�?��A�*������.]ڰas�z�a�{�G���q��ͳ~��g�����۴iá�5M��DFFխ[�l6��4q��e˖�4=o��~���aaa���۱cǥK��w������� �Ν;�?����ԩS � ���ׂN�8$����q����v��z�� 6��B!��l�R�RQu��e˖ 4��F�%K���/^ܮ];n�Z��D"__���R���2�D��R�������-[�)f�y�ԩQQQ�p�СaÆ�t:�TZ�n�G�q.�0���-X���>��É'R�lٲ +-���ׯB���h4��s��H�d�Z,� �͛7w��y���I�&5o�<??��ӳ��h̘1+W��8qb߾}خ];��F�`ذaǏ���>y�dpp�H$:��^�T�T�2���r����������������855�d2���p.�_s�ТE�R������Sa�@ �S ++��� IHDR������r���Ѻb���� pHYs�������+�� �IDATx��}y����[�s��콀�r#��r��"��1�`<cD<c����&ѯ?bB��D"DI�A/�CEn�Evaa�=�{wv����ѻ��=}T3;��|��lwoU=����U݅|>h�X�O�ߚ��!��r ++`:t7��a$�������='�E�@ ++M2�Zs�RI�D��m��'��+-��p"if^2�-}0X���M�"Y�>��4����$$ ++�0ƪ�����<��2�j������r�`�Z�U$���H&��2$鑰�K�h'���^ə��ԮϺ OO�҄i��c�%�� ���С�$?��d�o����3���(�eE��:�%��'iD ������^[�V��ԩ���&)�o84��"ڑקI25�T`2 rE��^��}�ZUl��������<Z�HA.� �˺�RL[��UtBH��Hp��d�u��)��<�����D��w� Q{�H�X���߷M,�4�� ��>$t.`!�&��������U��n�X�3�m�� �x]wt�,��A]���Te�l�2t��7B$Nq����@D�=�4�)B��ۦ��0W��fvL�0֭u�I^��� �b�����>QSf�J3�H$]�%�F ++W/5$#�V��� Ct�(�M�l�{����5�g���!o�ܶ��t���ct ��4��I>������P(���b�cǎE�Q���$n�)��& w��B&R�\*;���駟�4 ����7�t����G��=veee'O�����{����� ++��{233�m۶u�V�Jvv������������ɓg̘A.X�j5�64�k�x<^RR"�5h� ���'���������:t(��СC�ѣGs���SUTT�UBrt2��3��������z�e333ly�ڵ���YYYÇ���4h�����y�ٳg[�������n���,))ٳgϬY�JJJ���{�wݺu3f��ׯ�������y�d�Fah�x<�c��w(jmm���y�}��W�v�***���8p�u�]��_VTTPUWW7c��a֯_��7C2]]�,�}���cǎ���?���k{�1�-N�;��>p�ݿ��o_|�E��2e� 7�@Q�W\q�UW ��}��]t�k������gJߥ��9���ə4iR^^w̘1w�u���������p8���Y�f]y���={�6LR}�s<�������^xaܸq�-6lw�駟~�7�n�d����o�>�,�0<�����ݻgΜ�Ų����0�<���6�-�1��MA�r�CYY٩S��ϟ/������S�N���9�h4j�Zi��D"�Hd]w�qGCCCVV��b-A��0oݺu��v��ѣG���:�\��o��s��4���/��"�[���<���?^q�ӦM[�t������k��~��_x����y�g�}��W^Y�paQQ�=�ܣ�y�_~1S"dZ��7ߌ;�j���8p`Æ �ht���PXXXRRb�X����o�>nܸ�>�����a�8�N�2���c���Z� ++!���_��n��7r�Hnc�SO=��?�����=���F��� �B!�X�f�{����o���%���'�|���ﶶ����#G�TWW�3��[�dIQQQ�� ++{LT/d��� +++C ++�") ˲eee���K�5d���{�СU�V�u�]�f�Z�n˲�\r�����9s�>|��{�ٰa�����L�B(��HJ{U["�������E������px̘1����ЧO����w�<���ٳ'N�8q�ĭ[���'?�袋�����bø�����2$##c����^zi(z���=��?L�tCC�ҥK��i������Мn����9Ib�X�>}o��n��3hРŋ����5��'>��)S��A�n�;1�������iB<�����?�y�%� �����Ν;WXٴi�V�\9`��Q�#G��4i҄ �`���&M�4i˲Æ s8��>�0���/G�}�u�M�2��?���c�֮]��߿?yh>}hG��dۋr)[ZZh��8�����}��x���G���b�b&''�O_VV6a�����V�e[ZZrss���4̱�h��iz�ȑ�N�������0�kٰ֬a�Ν;�����?��Y�O>��_~��{��l����%K�dff�^�����Z����;~��3�<SZZ��#�(�s���}ш��V���Y��������Bcƌ>|�G}����V�e�]�+�͛7O�>���������_|��r]z����~�V��qcc��m�g��/]���7ߜ2eʮ]����믿~�����ߟK��{�-_����nܸqW^y�9s� O�6��W_�8q"WZ(Z�|���~��믿���+V�X�z���^���OO�<����6l�����ۅZaP�dFy P��bg|��A�����jnn����3�B!��A�(����|XQ��3�Z����mڴ������~�����?K�.}���������Os��Q�F�z뭗^zivv���?���@,�U�V}���PTT4�|��V[[���o<x��eÆ %%%�N�1b���#�)��c�;�+'�H���Ӌ&+ΥH�5�4��#��6m:|��+��r�y���7�8w��]�v755qѸaÆ�Z�eYη��)?� ++�����������TUUE��h4JӴA#W���i ++$�/�Zȧ0e 5=r$�hu��&�t$�-��,K��T[�1f&�m�p8l�Z �!�S��Mkb�����T������_V���ƽ�ʴ��N���b�X�lt8"�tø��zK2��JK�y�k��f&�.e��y�ä��ȧ$Qɚ�G�L!\bF��T��� +"��-�%��y�KԚFt�|��l$�s�4�sʝ�*��O��ж��a����rm0� )���N�+�\�D�K�#�V� ��g[�R��3z���l$*P�1���݆i����@�@}�<���JS¸�#�$I��`�m/��v�"m��<���Q��e�"�r:��¦�0!C�����,4�ꃣY�Hn�8 ++!SʥQHi�Σ)�`�P�B!t���H.2DŽU���IJ�B���,��P�^�P ��o��[2�l$�\�J7�����P�*_�5RE�� � ++��ro��){UR���y���RkiIuf aJ]ZG��T��3W�(�D^M����8�@��1yb�01���FӋ�U1S�6��R0(�,@7)�$Q0M�+9��n�$��;��F,Ykӭ��I_�]Sm{F�6��=�S�<�v�}tP���������z����*����}���:/��h�)�R!�4b�x��OV�Gؔ� !�N�D�F�>uh�m]��_B7E����&�zi(l�MBe�����n���J>�i�廆$�%L�,I+��nA��@�U[�#}v�����r|��`��� Iԋ����<n _n$�>��4�WY]��kr؝V�]=u/��@kSS�כWx�P��л�0������9YC��&��3';U.�]Y}��|f�� ���-��Ƒ��UI�q�� D�:=Z��絴��Ij� :/huإ���Z۞z�I ������].�za��v�0�y�h��m�f��āB`����TA�iIe��ѱZl��"y�)�f[ɩDrfI����/o7�S@IG��0�F�4_=Š5��� ++�#x����6!�`^�&,Q[ı�0;OR�.�j�0��A���3Z����_rh�����)]t��G���q��µm�蔣� "�������.9K�&�o��>S�1����56���1�d��Tz����Tt�l��x�YD��{��4�EN��v���-f�X�N��R*O.��҈�gB��䙉&0�����3����/�x![j�<r�23���3d@^�lm]l���~�a��<B�RC<�4��Z��D�#���1�/N�\'��j�I�i�wtZ*��anȔ%L��%2:�\7�V5�4E�p�G��g����_w/�u��wJ�9'/���u�y�ِ���CG�;NR�<�a<��ڒ �&��Rt>�Iࠬ!>}]'��DC9���,�ȱ���t���BUkԉ��$�Q�t�;R�P��2�$#O�f�<�u'U#V����v�a��M�Z@�2�*���AJ�άiJ�R��0���Fv���VT@Crګs��2�f���IXD!Plp C���컄2yyԘ�T+�p�tOQ��Λyl&�������*�Ҙ���� �i��R�s�:O^�)�i�J���v�1|]6��@�s�����w�b�7���d�(*�4f�H&���X��z\��)U�RH@�����a⚓�}�H��k� �8i�<f ++qD���$y�`a���Ѯ3'IlR�)c������w@���IUM-3��"ܖ�������¢3�X!A��RY��z]��M�b�� �'�J�y'$��yr����e���Q�.q�v�ی�B��*������� 6���%oa��DU���dR�T�nt-�`嶉If��U��+:�w ���H�y�t]N$U��N6�T�H*�r�j�<�m3M�i��*��oBv۠�YkI�G�r�����J>M*���RE�i&��+yR�τ1Ӿ���v�3�,��l,����2'��!L�+���Q�뜋A�uX��W�1��4���^Mru�4�'K!q9 ++3�QM>�@:M,L�t@Y�I^O� ɸ��$K��ח@�ЪI��-^��kdX�S~tf�ѷ�����%��@h�I�i�b.����I!�륺\Ҩu�����X�`���75��.]�ˆ�٥�� ��Q-f���d� ��D�(�dvtd�[���Ppu�C�ƌ��B��>\�؟��W� ++���&d�ץW8O�}q�A���P�`�=�.��1#kL��ylK�&���ƀr�D�m4[�jCh������[�w�Ⅺ�I��k^�G�[�(J\�00��Z����%�F}V3�WS���� ++z@&�vJ�� �+:í$�n(,��3iu(�Q����JN����NV�*�\�z�g�Qi-�d6�D�aK�����fq[�Yj>=��(����d�QC]MP���ע<'�f�}�}�]q�vFc�_����XS:~�������I��AT�H{m�B�A�x�!+����>+�T�<�^;�J��@?�蛡�l�0�r � wW�Y�4��Y�ö�&4*�Q-/��[��^��Z����=�K��Jآ�1ի�B�H��u���(����xG%��l�]�e��߲��.��D�yj�C��}r eбqKc��A� �Ѕa��ӹ�v�9-�?�N����m��f�/��&��"�4|u�zE��j^c0��c��ҺXAK��|M{����.Y/�y��D�����7 uGui�,IT?v��v�4�}[�5!����|�;����QA�j���dd��^6(�^(�R]���D��K�%���E���)FjB;�u��!#�UO'Y-`��9�)&J���M��5&9hB(���z�$��-)~ Cy}����(j��ǟ�?,��D��a�{+T^-3��W�s�jNf������(���xB��+}W5�<����>%(���6�L�aœ���'#ѩ�sE�EK�,Y#^�L�����iC�sYpIS��� �̚ш$�&1�q!��O��5���7�C �v�DC���q��!= 6p 7�gO*��ëȀ�+D��-���B8`�}�����ȼ�}�C�/�gu�1����LAF��5붲j|距��^�-Y���v@��f��n�)#if%��L���R�c����ܒ�"�U�ည��_�IA���ؕ$~�{����j��a�,��\SO�I��&� ++E��h��7kG�7�I��mť��%J����)9Ȍ7���әv�(��bb���H���D&s�V�AP�O�g�9�V�h����3�ht>c��W�PkeJ���b�G�Őձjo =kHܔ7�<v��Ix�_���]�xe^�,o�fu�2�^�=ڈ��v��c�A��oi"��4�rX|p���a�t5Hu~FѠ�%�1�~_���aK|{��h8f�S����Kdcd��YVcc �<��g��˂N������#���� h �`��8ׅs]��G}~}^fq[aH.��1�9,�᳣�G%��f*�z���̽�㻫�3<,2��(0���s����#rY��[C��+[��ɖe��1Vg�p����I����ʹE����+�łQ�j�O�"�\'�7���7�Y>+���>j���ѱ�L������}p�m��Ö�g2�N�s�}c7���>@��œ��B/�(D#�)(kBǛ�)�j� 0d��e�<��i ++yl8���a�q�9��6��cb����#��ݖò`�e���Nx����]�vT�Ma�-̞?�_5<>��iS-!쏢�D�(�/J}ߚ��&����F��jS:����ʚc�@˽[ϟ=��Z?jR1���N�l4 �P�q�n�e��6����2_����9.&� �����>T���e� 0u/qsk�����T��!9�ۊ�C�a34�`���^;�u�4���R�8�G�ǎL#�0(�.�.��N��U>��8�)��뤏>�;�c��ed.>3��0Tc|a�c�� ݂�v�)����� �"����F`�q�s�?�B��ѓ3����)��)�c�E �p�,�P@!�ua���?���)N�p8��X4�S�r�_�/|G��?b���5ڹ��kk߮a�����ح�5��z��%�v�lB��o�X3��v�w��D��yBԇbs:7�(#�"�d��p����f�ߨP��8����g*��K1 ^�a&n�;]�p̓'@�y�۾�2��^C�4Z��kg|�v��9c !+�z~��i6´봾�ȩ���pG��DAs����T���P����ﺬl0F@�'|����G�)�� ++w�-�� ++ﺭl �^]�3R�@O�����a��*;������;R�!��b�,%�?�i�;�1�Z��(#r��.n�#���l{F�����h]�&n{Gu9�xS��dʲ�["]���vW�>h��v+ 16�,Rz�u^ҙ'����Ӥ?ȶ9I�5e�h� ��N�*�8�̓J�u�f^k��P����֦�sF�)�}e���\$'|K�<�� ;��v�w�`j<O�Y'��҄*������b��cLzș&F�*<�3j�y�S���㢹�)�� �|��J�E �G�2́|waŻ$%(���t���=K�@L���UUɧA�U�H}X�C�\Ƙg��0cA"-�u1C�zS-��� ++Uf�3͘�u�P�*2�@R�p�?q�t��� ++C�6�R��ʵ��Ht�yc�E�i���#8'�5M�,�W�$�O�O�(TSv�R�y��F��ȫOL+Yx����"'W{ ����NӚ�ˣB�-*������q�� ���Z~��7�tG����d^/���'W)D�i��&���'����/`��R[�Q�00�|�-i���n7��!O/����1���4d��<�ʼn�W��j��℣�+�w�VM���Fu�!��%��u����r5J�+W�Boc������]�:�Re��̶��֪]� ++)��%����^�-���zH��<�'�.JLD�!��ER��c�4�!�&]ᯃe�5}�t ���p6P ++�)�q�����������P� ++~�U`����3���Y"��O��#_���W��P����QN���Dw�2�~��!��fJ�*�<���C���&�xٞ0��$�� ++M=�iBq���s!Q�a�n+�:�(x5&��:Z�9]��nh�m%l-�FG� ++Li�D��WUc qʬ�Y�+��BQ.v���:�)I>?�F4�����@YQV02O��]Q� ++�>��#�S.�[t�TΛ0�vjĮ �Y:�C���&�=�J��Ҍ��4{=BT���*[~Bը��� M"$r��T S�4�$�%���-��F�:�Ȭ�+Ș�դ�0\�3���+��㖒��7��m��I{c@]��qR�����5�A��K=C�:�� �IDAT�h�Γ�0+�F�����O�T� �@�� 9��O�ITl\�CJ�tшr%�e��y�(�N�B����䑛m�1'y'N3����\��r)ϰ��)�(�Q���,� ++K�����H���)xU��)Y~��0�.�xb�I�Q�\��ʓ� ���pKX~B���(VB!��n�t[RۉI&��'�!a�G �P�A�apBQa���đ�du��j23�*$S��Qe,4@>�鴎�Zg*�B�6U��R��EQfY�S��Γ{&�˙�Zw��ϙ�P!�j���B���FO� ++:���2_�x�j6fY����y����H�ɩe�JW��EW�E:���'L�{��?��Q�R�'<|�#��0]Y��U93�g��zBlW^�Y���:���Sُ�A>�L^H��@���P˦�H�oo%ym�+�y��8Vj�����Ň���� ����J���G:����(B�� ������+�H��)����`�a��Qg���>��(�K�=<0Ş3QW(D�x�/56�䓛�t-9:�**��L=�i�J�����T�[t'����c�i�.(i>�LX�ruIO��a��n<�-��YuzrNU ++�O���jY�Am C�V����O�zS V�AQ�-X�|��,�|d�<2z'��'�������J��)�$S�.�S&��#G"�K�9�J�ᘣ�̆��;�9�X���(G���a��iJ��@N0�ER�+C7O,r��ד��\�D](9V&�:}E��e�� �a9� ՞�J1��,w�0�L9��(��JNf�.�֡<�4�!�a��4��oB��pA������grJT'0.U����:�8L:��̢K�V�h�*� NP����-p��db�����HT鄉X,�km%��FM��p�0(F{C0fYVxќ-�:8G�T�����������V�Z5t�P��^���/��|�qc��kf�&9�#����F#��Æy�np. ++9r��v:������***����A�233�ĉ�`������[,�w���:4nܸh4 ++^B~~~~~~{ ++����0��4p���A��h�����������8��~yy9��4]PP���K�B!��(������ĉ7n�~�����+W�-�O�>}��aI��;�]$y���)��.�W۶�s�=��c������˳��ZZZ���gΜ ����}�QVV��j����̙3lذ-[�����@ o��&�XG�6lZZZ��e����ٳgs 8�n���YYY6� �233�ϩ�ڕ+Wr~�i�ĉgΜY{�ԪU��<�L���c�\����cV���͛?������i��n���ڧ�>������o��_k������s ++1v�X SC�9���۱c�����Bmmm���۷o����Z[[_��)S����u��]}��g�u�TVV�嵟�x�Yg]r�%����s�W\q��,[VVv�嗟s�9\�m۶�4=n�8^�X<�0������9E�0���?dȐٳgsR�Ý���z�-��r�ȑ��ߗ̘�v�E-2�%�b�� >�]{��_|1��<y�駟~ꩧ����`ǎ~�!��7��W^��>�E��?�\,�u�8++K8*���(,^�4^�JKK'M����@QTnn�P��'O0�8=�vWUU������s����BQi�h4gggsVTT���9�NΥ �۶m���)� �A�(++���>|���)//oll��;��ݛ���[���\.����5�E�)2rРA�'M���GQԌ3�V+����uf�x�]�~��e����?mYX�-7��Я~e��"y~�n�N����l�b��ZZZƏ?k�,��mmm�~;������YW�����=����6���ٳo߾H$�v��>�l.Wii�0�}�ݡC��������r�jjj6m�t�w���edd��v�ew�܉��V�y'r���dI<��b�]v?q���� 6�,�裏>��3֎C�8�?��OL�>}�رO=�d,����?��Æ ���?'����41Red��<&��i���o����ɓ�����4M�n)òV��j���q���UUU���}���5z��ɓ'�C�={��X���X%%%7�p_Qii�!CD�{�އz�So/���{sssc��`�+++}>_SSϼ���gE�������٣G�Vo����D$0�@�l���7>��c���<���z(..架���p�ݙ���--��{�ܹs�{�9�����Ɓ��� �'����̬,����Gq�$����mmm��1������������b�O�>s���3�ә��ۿ�pҤIuuu�`����j� ++=К�����f!^�@ зo�`0XWWG�����/���.G���<n�0`@YY��>�X�O ++f�/������3g��y�M��p��_��W3f��Y�f�СC�z��Ŝ� ++���ꫯv�� �^x��7�,.7A�I��,h��(��5v��o��vԨQG��Z������Hd���g�u�g�}v�����4=`�����v�_�~������F~ވF��?�ٳ'77��v�����+����p���`�X4��_���{�����8묳N�:UQQq�5����o�ȑ|���ٳ���kjj8��r���(����-//���Iڮa0:�^�2π�[�vmqq����}�QЧO��_~���n����d<����|衇���s��l������{�\%�rH)����dz`�y����,Y��b�\}��N������`p̘1Ç +++{�l6ۜ9sh��i��[o]�~�믿�1����|X�ػw�{�NgQQ�O~��())�5k_i(�~�hnns�СC ��'��_�!4eʔ�c���9s>��e˖��q��s饗������4���=cƌ1cƨ��j��Z;�$��/*l��3gμy�F�y�y� �����ܹ�^ڰaw�����}��ǹ?93e�������I�O2,K_� � �F9b�˲c�7�8�Z�VQ��b1�a,�����K����2&�B(�q*D�Q��Da� G".��3() �Hq�������{�ͶV�UD��G��b���a�����ohh�����Y�B� C�k�)���mgY��aD o�� �b�=:b���K��v�]B6�ҎK)�I!�]Yh�-@�� ++ӪU�V�Ze��o��Ļuuu��ͣ(jܸq}��Q-Myz5�ž$(RU�u�9~�xa �E�8��ʯ��zįlv�+���҉d��&�l6�3�0�X�� ���b1��� ++@y��yn5pQ�_wU-%P3����cǨ���!��h�m�Tq�����By�<�$���rp��}U�Tu�>�GȈ�;D����S���i��~h���Uq�mvz�z�$FRȧk,̙d�i͢��0�jm.BW3EG.S�P�ňU�I�+�BB�)Zx PogX���}[�g��gd��}�TJ#ԸK�$�NB��[`�S�UIx#[��c z}���IH>�ZL|�d>I��BL�y�E��H��c���KL��4u��deӲ������iVO���Agߜ��ה�ւr8�1 ++�3�R�W�C��^ڥmL��%ɮc,�m�#�s4̶Ƶc/N?p� �geu��*9,(|,���]N/t��mSP��nW�y�*Q��{�[��b ++�S~�%��Ȓ<$���/�&�۾Łߠ�ܷ�� ++�֕�k ����oJE�XIH:�(oz��0U*���1���d��0�)Y0� _n�r#T�3k��i��n���$<~C"�V�,��F�N��K8/t��^�M��H����s�G��QY�N�D��e� 1�&���V�H�� �T�yr���W̒�O�NAԮӵ�<�Rr�#�d#8��G�Ӡ�ƛ ˼�N��#���V�0� ݣ�x���}�e^���G>�%��(M0����5�H:NF'L�����Lz�{� ++����j*;�4�]�a�6V�.��KD��k�I%bϢ�z ++����oCv ��8���������FD����f�2-��6ο4��8�%���X�C��=�"H҄B���*�,%%%ܧʹ��_��G<��;HD ++�Y��c0���S�@�Ȯb�)�*�S�x������ի?��0�M7��ꫯN�4�K�jժիWs�'}���bŊK�.]�v-� "o��FII�_��={�p�Q�[n��t�*T)�%��|ǎ�Z��F��i�������O�r�rrrD�ͨQ���<y���a��ܷ����G�����������w�� nO���*,,�r����}������?ޯ_�ij�)))��b#G��?��Ŏ?������F�@�����I��|Ҿ��6��Q[[�c��O��[]]��O ++?�8e��G�jjjV�X ++���o\.ך5krrr����x� >��������s#8�y�}���7o�m����s� �����k����i������ׯ/,,<u��7�|s�-�;v�����F�y��go߾�����JQ��y_|�����7m�4o�:t�믿����8ꔕ�����_|q~~��-[�~?�-��"<h���'N�X�r�g��}��ɓ'O�<Y(��5k����v��={n��v�3��@YYY�7o>��f̘Q[[����4�eٺ��ѣGϞ=[_GɁ��ˍ����555���WX\\��w���,8p`II�Ν;���kjjz�7ƍ�x����օΚ5�{�}>ߚ5k������.�릛n�K|���y����{���~!t�����۷o�9��������p� ���>��^���������WVV��^z������_{�5�(�ݻ����>|�ƍ�����q��A�y�}��0��ѣ�ϝ/]�t���\i�@�W�>��s/������7�|����Q���9z��E��V�+���1���ߐ!C���J�p�M7�D�tii��{���>* ++�?�'�R"��� ��q�V�^ ���>�����z����b�L�0����x6o��Yx�p���^���mii���"����_�~=Ƙ�~7��u�]�����_sss�ᆬK�VVV�u�]4M��\�x�;]cٲeBy���:��������BH���ƍ/������ݶm����\��H$��k����Y�X�---�<5��h4 ++��������\.����N��͵��������+**����}��������n�766.X��ӌ�NZ^!!��3�H|P!����-^�a����/_�|ɒ%\�V�#�<�裏<x�����̜1c�E]�v��[o�u����^{���_?hРG}����~饗���x��k��f]���b�����]v�/�p���^w�u�<�LQQ/L x�����J�� ++�>��n���)�o;�ξ}�r������\��|�e8�8m͜9�ު����bw�y'w1;;!t���h4گ_?��w�o_8v���)g%%%�������O�8����c68����6���lmm����x<�@�v�����[G�>�,w�̙3E�t��K���mQWh-!���t������{��wߦM���V�Z�`A X�pacc#�����رc6�-//�3��u4//����K�,�9s�e˸9h�����^z�m۶���~衇��|PAZ�M�X��������M�6M�6�w��=گ_?�qa555�P��3��nݺY�f�w�y�x�СC���c�~��w����S\�cƌ����~�ӟ8�w��.���>�.��2����������j�r� ++� ���4�0V��n�s��WVVoٲ��?�� �͛�m۶��b�C��";�B��e����ͽ�+f̘��x~��M�:���/ߵk�'�|r���Ϙ1cŊ�g����~�)�<�쳷�~;�8������v��0,�2C��/~�U�V�۷/�IC������y�扦<!�m�U��D����0`�ĉ|���j�)<���999"�O�<95�r��l�«�ѣGoݺ���9s����������.]�����?>��B�}��q'Dr����u��Q������������y��}����֭�+����|��8q�?�O$<�Sr?�\?~���T(�?���;�|�g�����OΝ;w���������ݻO�< ��>��/�p�ԩŋs��?�|�GAA����{��677s����e˖-X���x�����5++�����{�^'��h���`����7˲ӧOonn�X,��inn������Ғ!8Iq����Z��P���������A��&��STT�t:E�D�Q���w�ޝ����x���[�v���d���[�l2dHVVV,���/�N�:r��O?�����;��K.�ӧ�ȑ#];{�쬬,QT���s�oEE�UW]�:��D�d<ڣ*"%��A9�M7ݴ{���9�ᇻ|�c� �L�4�f����ô����g?cY��+����@��m����e˖]q���;v����_�0���ݍ7�:u ++������o��F������9�� �;[1�M�>��/^�|9EQN�sΜ9�,�\s o`���ٳgϞ=.�������g�555}��g�H�3��f����;v2dРAW]u�;�ò�i�8'� ~f|��3�.��1cƨv�21D���D�]��"._�|Ŋ������s��]�p�0�1��^�4i���{���v��E�.\��_��G �G@IIɍ7r��D���O<�Ĕ)S~������O*))�����m�&y��N'�&��.�0 ++�x�����|�7�|sѢE�D"\���º8cF�GY��t=(�|��z�"�$�tKK���ۿ�ꫯ��:##㩧���K�o�����m�ڵS�N�2e����@<W����/�5j���v��駟~��>���_��o��_wpѲe˄k7�|3�Kfee����B���˹�;B�)���%/��GӴV�A���xBH���uq~F�7i�V��K��9�g!� �p���ŋO�6���\`�Z1�S�N����w��/�������߿?B��;�<xpcc�K/�t�=�pS�xڴi�V�z�g�n�:w��h4��v��͛��_.z��֮]{�E�f=r���}�����&L��##I�$"I���į�s�7q>)y���u[8�Z�����x�Y7tP�$�*��8u�At����:�j��dz���$fS8���O|�Ï�~��t�i�v�v^�\��0�|�v^ ++ئPo�ԏ�է\#Dv�ۆ)&��0B�th#!�t�=!�|��3Tn�C���=������Er%h�#��NN�����YR~ig��d��q���=����d�=�=�|F���2���CI��g��-i��|���mA[�B��ɿ����U�^�-B.�K�1Ą0�>h�ST���];�j��^�0Ƣp����oI���%�/z�udcGvp�M��in�MV���YD0%Ġ����t陸� wK��@.��"!���!|�$���Z)���!Ib莆��I&B�$�H�� L�<���GR��AuÁ��R��<�A�Ӵ��m�) �jR�bt7�jժ�Z����1^)b^�+��2 ���� ��:�[���#�ER��M_����l�>O����,�m�:�w�B�Ͷi>!�坌I�9y�~I6�k�]aw �P���:�H/w/���)�,��{V5K�7�$B����:LT�V�WR��%���)�o� ++ v�B��)�i��<���� ++�C ˼��&�(�Է4[/S@GS��ͱ��;�)[�IF.#1<76�@��n�&�|��6���7�Iv��Tۜ$���xJ�NSb}M�����y ++q��[>s0�F�:��PtS��S�*��7��fsx�Yn�7�q� ��ȹ,�UUs����;-���. �Q�H��JF�@��������߯��q�L����a��������o���:����$Њ�n�2�MF0���{*���1T�.�R��El���GT��d#�S��>V�*@*��J_&��#����}������ W� F0�sؕ�Q�|u�N9���틖8��� �IDAT�Z??��5��S����k'"��rՙ��`�v����tf/&&�����y��h�j@(�����R�/ք�F��E���Z��$�[�J����V�= �.���pQ2��@rJRR���U}�G��m�~7-����k�]v��܇����,�Ɓ�d;����f[�@���fJO��Պ��G+�ϜE�._�̱��ذr�g�V1�w�hwqN�uP�+�@2=�x)1���7�u�n�o�]�����#D��[�C�]Q6,���NPig�!����KL�U1H Cʉח���S�6��mL�d��P��8��mn�߬�MF.�����B�F]:!�ᡴc@�+EY���`�-1�~$T��L�+��δ�����6ĢB48�+d�`wϊ�K(����떩6qdݮL�� ++%h�%%S.�f�{"���{>�u�u��;��l�\��Xe���2�(C�"M� ++a��sl� �gI�#��R*�K�������'��O>Q>q�s�B9�ǪbͲ��q,�Ϊ�V�!�q!D�m+��T3�Zr�L�k�ʴ�eYs���\KfK�!������l0�m��F������ւ,m��D�LȂ� ��0�ϴ�F�H{Q��d���[�ؖ(�#��maY�f0aC16�a��Ś-Ȓm+�1�rX<��o ǃN��9Z�;i���V����錖xc(�P�8qY2��� �o�ַ�id 0���Z��6ew��;i� 9��,_�%��VD7��l8ʆ��D�Jbo��dF!A,�w#�<> �NV� �x��G��L���)��4�W��u�'��<��^� �2�buq�E� �(D#c�� @#�1���hG�l�#lG�(�(� ++6�D#4 T��0Cgc�MY��D#ڂl�h�Z�5�C6e�f����2CS4 V�X�@�SE#�,����Y�P��0�ap�B���";���(KGg���a� ++he������Ve�R��c�"�bp����1��4���(B�6XQ���(�����%v��O�9��w%�G��Ab��Y��c�C!�%�5���(�dZ��+�9��D��ؐ5̆!�!�ַ"\c���!5���r���5#����T*�~��Ś�ϼ��[u�=9� ������ ����Ӕ���@���I��5�}�mM���0 ++�X�id��B��8�P��@����#������ ++��ga�16�h���q�*|��R�4�\��6P� ��0^�#5m7yg���p�l� Z^C�l��vW�L��y�z���#�6��f �� �&H�^��r5��RB���#0�B�����oL�y�`k ��/����x�bQ�զ��f �I�;�tb/��D�%��{�Hu��D�vy�.oQ��� ++�|fA�ĔԽ[���nZctz �?�����0��ndVQ�з�'yP�G#"_�u������j@���iB�����4��R�<�qH�:���҄WR=,�|�#��+�����.h�x^:7���t�U�5�p��C����������,I����)����Ew!m�'7�J*<�9ڄ����{�k:��ޒ����]�Q��B��P�di�q=��tH�s��3*EUT��!�k���� ++g0���Pۉ.*D(e�*r�R�"M�z+P�i tl��'+�~�"=��������ݤ�>�I� ����~�Mr�LnUC2{�N%P������W�W��J��C�?�nTZ=3��Z��nb�&N�<��.a�W�����~��f,��:QG�����&��:"��3��R�)�>����1�dC����a�H�5��d���4;t����@��٪�<&�<n ���a�.���1����+&����5��S����$W)�kWؙܾnk\�$���Lf��N]!�D9z�:���INPi�>� _(�̛��K��<}�5,�<I��OӨ��<S�"��5�HC]ң�F^1����UIE�,�iIlz��^$$���y�S�Y��^pw-�)~ ��if�@X�/J?/��~/LG�-M�τٶ'r�W�% $Lh߫��Tғ���Ewm?֔^u�,R~�L.�&9z�sA>֪���)e�<����X�1�Wm�a��p�jYx�BR�$�ە��4e�E����-�US�]R����J����3��ܒc��^�LJ7@�j�wu�9��0��9�������bڏ����H���'l�!�1���.O(���i?9F[�L�|�7�����E��a���@�ӕ ++@�b�v���;\�0��쮌p��X@�7��tzB!�8��P���PͲ��@�b��c��w�=����a�� �������Nw����Dm���`����+�.L�b�����j���t�C���p���a㘶X0���1W��.)���Y���D�����o(��Ga�ί��G1�E׀O�1B�c���r�Y��,��'�.Bg�B��=-FaQQ���a�j�`!q�eY��d4���:�����BQ����CQE��h�u�A r<�����_���䮫�����1�*�9����,��q�_��ʎ��p�m��@�B6���z'�b���e�l:Y���%/�^b��8�@���/��e��>;�0�P��F `A�x{u�NKn(.,9N��=+Թ����;-���X1�o�ӹ��맑���P���GO��.B��)ǝb�H�d{�:a�a[��猈������������sz�IV��MA7�NS�H��Kv�/����dR��0�ե�.�l�O�S�c�!����\��$I�]P���+��8)����3������tSxB����L>��)h�2�L�mI�냜�I��FR��k2fd�K�r���j-��Le�U���L��{�P���Uf��8D&�4�_4�]a�H��'\r����,�m��J^7Q��͚sI`bE��B�-�RG!(�}[�+��)�J6e�O��R���@��l�ȶ��T��鮪ͅA ++�`�G�n�n�H�U�� �R�*RC��YJ!n��X��+�#^Q(�x�谑��ߪS�\�I w+'���o�)�0�B�Z�"} ;OG}���u�d2}F��,ơU�t�N%�3rJ��(�T��4���^���q+��HO�)|�H�lkn�iR~ ++E A.�6�0I2k�5���4H��5�v��C*C3*�O%Bw#{��3QZ5��Dh�%�G����>��A�Ъ�H�k�օir�� �0Oߐ�� ++6��"����8Iq����\�I�qtÉ{�H���XT*-N����&\�ł�E%c�mҚ@��Jt�[�%�&�ߐ~;^u�2�H�m$�u��YC��7�H�4��[���Ͻj17���Wr�O�LS��f�����L A%���$#�qzIΪ$�E��G�y���u�e���&��v1�Q~^%��&A2J���)q ++�(�eY�xT�z� ��K�R����9"�%�:Χ"���jGy�*:Ok4H�7�u��BȫH}v��^�����¼$�}e�X;*��'&I�����S��[<=:O7RC�4Yw{-���[rw�`h�%D*I����l��� ���c�"9ҧ���jS�xF�?�b����.M��9��I\�F���K��5�n�v����RC;!$)����� ++a��L摏k:3��E��pWt��u���v"� ++/r*�#��(3T�ĺDjH�6�dCu�J!��J#T�x�V�%u�ø�eH� M+E������ ++��d���V$1���[&�y��E^M�Pu t�}r��|c��v�x<��q8�K#�%�WUU�:NQ�ᴇ��@bv�����$j��<���ի�s]s�5��֭[�|��U�V�4]UUu�w����'O���G9rD����?��£��vΜ9+V�>|���:�:k���3�D������A}�Lu�˲�/.**�x<�w��`yy��Y�8������:u*M����o0����B�����:�ί��z����Ǐ��*�������Z���]q:�999ʭ;����P�3�ɧ|]�:���կ~u���/�|�����߿��b�ƍ�{�w������/kjjn���}��UTT|���S�N���;���c�=6e���ɥ<�s�|�I��C=t�g���ոlٲ��~[x塇�Ϛ5멧�"����>�[�-P �A�IޱcGuu��_�lٲH$r�W=z��O>9��s��"����?�p��={�����믿��?���شi�����$Knmm��I�&=��3�PUUu�-����:t(���h�s��#j���4�\�^x���6333??�W����g�=b���/��bEEśo� ++�-Z4t��I�&�y����N�+��ؠ����{�ԩS�PZZZSS�o�>�������p�)��x�.���v��f3�]=�,QU��ķ5!��������|��f͚u�-��ݻ���?�'��f͚0a����ssso��ƪ��W_}�?��τ N�<������[o����Ng4�x<\pg�-Y�d�ԩ�G��͛7�8q�/�СCw�y'�D"��ӟ����'N��2e����`A"V` AM�y<w��������P!����l۶m�J�}��o���ѣG�͛����nÆ 999��sό3B���o���c�͟?��G �����]v��|�ŋϝ;�c^IIIcc#W�i��~����ׯ_uu��Ç/��N�����7��б�at C��?��f�}���[�nݰaC~~�믿���swY��K/a����N�8����]w�����?���\�ѣG�s�=��������|���<x0�����z�����ǿ��;�htѢE�ׯw��,H���XQ���a(�B����7�x�;�@�]��믿^�|�����}��\�<��#^xa�>}��07����{������o�ٳ�cթS������Z�f�̙3y�����s��+}��o��֗^zi�֭�_~y:����`��5�-)��O>�daa����O��������ÇꩧfϞ�%�0a >���x��.;v�����喖����#F���w���n�����ɓ�����,**z������������"y��ҝ�V�/�n��+�_\}��4M<��×_~yUU���?y�$�X,�W_}uٲeg�u�E]�h�"Γ�뮻����2d�lٲ%##�����_|��w�x≁~����`�������3�ZZZ��ݻy��7N�8���<��}��=�������z���3j�(m9���Hكd�l;x����\��(�+������Gy�n�_s�5���k��7o^~~>����)++��V�n�ZWW��x|֬Y���;w�|������e�ʕ��;��"v�w���_�:}��_|qҤI�P[[�cǎ��ܹ�ԩS��͋-J �Z{f ��ih�b����K�A�\���(ʬl\<��j�B��[G�t`��$�*�!�%�S�=�"'�ddd�I��a���$+�:jםK�H�S]:�T���[�["��n�B� �Vڑ�B��P�d@e�NG���0�U,ASv�u!���&�T��D������:`�h�8�`l�琐|��m;�U� ++Ζ��BU����Z"YK ++�э�Wu�,����]�z��iC�m�E�8h��`�d�G )M���`�~����ӊӀv<�}���5z���3��;��<�=��7rP�^ ��X�;��3߭砠z�t�[K��)oE�I�0�ͻ��=�aIB��G��]�z�y�N���1��/?���7��`�N6�@����y&���0�]���?��{�|u ++Y�}c�\�Yz���'_��$�t�V5��o��cl����B���x��$,�*0�|Ɇ�o�I���f�R��@})[���ij��a������`��������*0��p������p8�V+�`��OY���r 5'�0rR!��� �'��s<��R��u��x���/���D����y��g��Z�J��%K��ʕ+?��sS��v`��,[\\|����vZZZ���:~�xmm-�����СC�x�ĉ����������x\����ëW��$�нմ�f�XJ?cd��~�dR��nss�ʕ+ ����������3w�����U�V�{�����H���v�ĉ���F(���>�������d��w��}���'�U�V9r�n����lyРA}����|o���رcG��y�f�ߟ��������-��¿s���3pƛ�� +++����o��n�$ǠI�xW}��:th�����m۶����S�644\|��?��O����r��s��VVV��~>cEE˲�}�ݚ|���$B� T{U9Auu�ѣGo���[o�5~���»�f͚9sfb�X,�r��>}�̘1��2z��o�����z��w��.�,[VV6l�0����?t�PCCy�bf$��x&�:��%.Y��a�h4 ++��X�b�p�*VWW:����s�1b��nO����.��o߾^�������������/��J�~�.����IH�FX$� Y¢ ���-O��L�go�L���3��|�=��*� (����[���}��w����$��u�N�Z��E�=<zSu�����{��=KIR����AAAE%''��׳�FFFzaH���v�3�<��Cv��b����PWWR^^�m۶k}���555Jd"-z�''� ++�l^3Dh��tM��̭れ�NS����x������ׯ?�����N��w�^KKK}}}[[���ܺukNNgTmhh(//�(j�̙z��ʕ+S�NE{�U�Ԡ��";��������&!!!===��\�|�f�����wi���Z�ְ��x��UYY�^UUUjjjaa��je�#�ȶ,I�y�w����� ++�x�ߚ�g�Y�r��GSSStt���ӟ|�I��6lذe˖͚5k����G��5***������ݳX,��#I-qrqzF�� T8�O�N�|Y��r�8�v�}Ŋ��̙3L�999�֭[�v��ѣ�oߎ.VVV"#/??���i�֭h�>o3� $i�L��:G��.���B������H���B���z�=n&����7n���C�������,�3����>|8��iӦ���VTT����5*111""B����B��U]]�~���r��yyyYYY.�k�����������Y�V���L&�ɤ������č7^�zu߾}s������W���3?��0��2���>�Q/MCP(u~[��sжc'���BT[�~��ѣ{zz._��؆��s�ΙL&�����ھ���ݞ��������\\\��P>e��7n\GGGSSSwww}}}vv��nGG�����^�i���L� ��ǏOJJ:z�(�h��M&ӽ{����ccc����._�l2��L�����~�*��6T��$�j�����ft���G��q�b��J��3�x� �պi�&�N7s�̣G��t�����{̘1�-���6��T\\���μ@���III ���BCC.\�}�v��=s���Ç���_�p!###,,��w�E��x�3f<��c�O<����_[[�%%%%%%�����ɫV�����'�x�h����<v��DFF22�@TϱA1!������P$Y��E�{�;������/���u��͛���111?��ڷX,gΜ�>}zDDĦM�.\8a.�8qy�˗/'�e� `�q�\.���yN����j#M�}}}|������T�v�-y���2罷�������yl�c4���<|�xhg�X��~����t������`�� Þ={�����s��e�9�Ѹ���Ǐ/Y�d�ڵ���}�S��Z��M5��F[�Y]]=v�X6c4���U*�<���L7��IV����ڵ+!!a���۶m�izԨQcǎMKK���gΜ�v�چ ��A`ӦM�����/FG�����߿?;;{������K�IM�i��䐡��m%I��q�r�8U;tE��UH��J��JcN�� �IDAT'�v�[�b���<�����-����]�����KJ�@riu�������[m S]I\�U��Q�p1�hv��B�e����کv��w�j�C��.�J;e���m$��)EӐ?T_�S2hGQ�������R}�o���<�c� �a(� 8PB;��兦�#ɫ�.�H�W�v���W������i'5� �d���Y_\����v���+:ʙ��:���` �t�@E�ɘY��B���S�T������C_��ʽa6/|�9n���f�X������=�M`�e�4m�X���@�PvBU�� ++}/0Z)-D;�~[�3�r�@)�]EE���<���5t�^��.)����]�v�\�����z�j�������;�&\����{�]�v ������СC�wkk�믿���"C��n��������h.�����يK���;w��m���8�m]��***���'U$�+�\���.S��b=�%`^/�=���b�\�q��f�j���� ���9r�Ν;�[���gΜ��_�����i�nܸ����'O����d�1�@��[�ٷoߙ3g�\���`���3gΔ���ر)�'N���}}};v�hmm��t'N�8~���+W�9��[o���ݺu�Y�L.� ++�E��*�}q����h`峰~�Xs�6�~`_'BoooyyyRRRccc]]]tttcccSSSnnnTTTcc#Z����3eʔ+W�\�p����n�����[�n������ܶm���/ ++?؈$֕10�mѭ�kY��l6�Op8�}�و#fϞ�*�0a�s�=��K/EDD\�t %���gƉqI�VW]9���� �t������`��f=�$�z����x��ŋ�n7EQ�1s�����KKK��s�j4����^?q�������vf�6�'��O���յ�Tg6#^}}=�o�h�-�1K�mRNNN���7n�����n��8���v�Պ��� ++��� ���8x�`RRґ#G�~�i�V^������ ++�C�,����Ap�4�n����/��[���H�����ӧO����n����~�0[�\�t��ի���C�;699�z{{M&�jP�LU��;���iF�7g�-������`��W�\��o[RRRZZj�����&N��.2��*++G�]XXh��x����$ �Ѣ;��!6��)<:��=���Ő��u����H�i{�����ZmBB�F�9~���l����t�S�������={vAA��D�x��Ri'i��h�Z���h+.�}�n�/_��믿>{��#��9���ӦM�Z�%%%;v�ذaEQUUUh7P~~��={�n�:s�L!�Oȍ%)��mQ�lޝ늎ҶY��Þ�����d����������y���Ǐ6lzAΞ=��ׯGY������9������ѷ�y�瘟�����o�ފ�����������t:�_|�ŤI�8�m5�֭[��۾���W�^ݿ?�~[�f2}[��]c�Ηp�������Rd�X>������8v�X�F���ɫ�������rss����D&>Ć�2�bԌ<4Ms��N�0��o˹��h�7n\bb"���v��h4w���$666<<��� ++},���ւ<B�ϙB���y���s�����L.��Ǯ]�ǒ%K�N�|�p8n9gΜ��D�J�N�ŋO�:�p�B��~���>�lJJ ++�̾�O���h�"f��#���.^��������p�BOA�8�̝;w˖-h���K�.]�����b� ++��+++�͛�m� �B�mU�@���*��p�^WQ�o�`H���K�9XGﴷ����N�sŊ#F�p:�_~��7BCCׯ_ä�������srr��[�p!s��7�|�������c� �֞����f[r����q�\.�9�BRy_���۲e�+����^��n���l|�ωyOfr�ϡcN����7��4���犋��ր�ɽg6?���y��իWљ���ʕ+_|�Eoo>j�Z��曻w�:����̜9������#''�����ZZZ�Z�N�kkkC>/�Z�GV*�yE�U�ɠ�h�[�R����L0�=�}e�O�`�\���b�o^���f���{~>����? + ++��ə4i�0jkkoܸQUUUPP��h�f��ٳ�NgyyyYYY__��b�iZ����z�^?~�x�.Tw�#'���G(��#�\��f��y�^͐�Tf~�S�-S%4�M"�B��y��"��?�c�s�����yB�b��~�Ԛ� ��O����d��?�ϼ���� ++�����NR?��f�w�H�d��ߟ�ڇ8������$�5�����w����H��;r�d��F��pew��1+�����9r� �`h��OE�ɘ��W�ZP����/j�8�v��Y�q���YH.ʃ������C>�2(?����H� ��H����<n���0��-�,�ç��G( ���%OL��@���]��w��O��(*�"���ً ++�@���PE��n���=�}�n���n�;��~F@ �~�uPPpXhTx���*�iZ��Ä8hj���� ++6��tA� �<�mj2�tu�FD�&%��e�A�0M-�&s����!��#�loE��ϭۗ�Zn��G{�F/m� ++�I}��ά�<��16�U�m�T�͘��{�b��'c?kr�4������d ���k�M&�3<���2���V�����p�����p�"�K�Hr�+3! eǢT�h�~�[���� ++�I����D T��h��8��XF3���S( ��X�f����'�d�o���KQEVA�4^�)p9����hQUd����&s�ٌ��yF�<(��)�O�c������s�!�m�`�wR�_�����2����)�֍��>!{�*��a��a������P�IŗZ�.Qvyw�$〿9�T��S�:56WI� E�@��H*?6ݠ� "�,-�Ֆ��O���v Q��t�(:?���%���Pr����(Qg�G l��T ++Jg����ʃ�}��|`���M�4���@N��0��w��z@5�"�"��x���D�ġ4�7t��@z;���#���n[1�W�~A��Nj��`h?�M�R�V�d������T܃�VI�0�G���j"��\��Wz|����P�AI�K,^,�2`l ++Ż��h��������.�Y����%z��á�è�\HUL�9�������#��b#���4���1���ʃ�E�H$�X)|0,z�1aPY� ���Γ!}xXTxXg�Ā��O�s]�/��[�-<os��rY��R�} .��� M��I�ǭ��O��=��`�*p��4��Hb�)ӿ�@QB;v)�Mw���0Wm���� 7{ѳ}��� ��V'�<dHBr]*������ٲ�ĐQ�7���?��8 ++͵�xK�њGD��y�L�|� ++gd�}I�i������/*�e�TF��7 ++;����Q��_�|��t�h�@o�0xQ�4(�a^�S�)L��4�.K��x��y�dQ�w���#uH9d�&���4\�V''�T&IL,/#ID�3���_�@�!$u,aG��(|��7v�@e����2��5HJ3)�9��E\�!��Y����4Y�$�sB�����W'�Qr�x2��P܊(��'�m�Q~ g��k��!Tp$_u�� ++ ++�i{�gC��$n�@�:�ʗ=���L���W]�� ��4%룭#f��+���0���k^�'1�ՈIBT����P��8Œ?'�G��c]銖�84N���:�U��#��N�)��*��[��!��VYA�������-M�_��œ�S) �v���9�D��?�����K!��m0���!��9��b�zdK���Yx�Yvi1u���P�]��A�L�'F*�ܕ�D6����8�0�d��pFO�'+&Ga�GzB�q<,ݠ�h�waX8A�U,2G1���T�\~�r�Zp$ ++VF���]�I�����7��r�����h������%z��ǟ�b��Ci����ͻt��'�U��y���g�0_��g�X0w�Zh�T_�������8�&q���d�t�X�o�HTEB_�R��%�;��iB)mtջ���gz@1r���ƐO�6{i��àd́z�b�w��Gt�� 3$�����h��n� ���<2������2�I��5������h���h)��[.���F��3,Y�X0�<$� �x�1= �s��-�?l�Fs���KZ!�ffyٰvi�F�-�pQ� �F���?��Kٰ��^����9%6'��h����`<�T�5�/�F=����9l���z��J�����hɲ��R�&�E7��axZ��/�9r%i~����zwp0�N ��ܙ���l��c�j���B���s' ���,BB�W������ ++CX�$GDʔ���8�^g�\v�e��A~7&�IQU'o �_�bu�܇ө����T�x���"��$����%��0��� �Rq�I������ԡC�-����sƀ�,,J ����a�Y{i�;Z=��˟A�FDLד�}l{?$�0��ɟR�뇩��A�o�����9�f�h(��>]0�5��}���z��&�����N�^TV��v@���Y�h��/ ++= �ذVŤ�5v����F+���P���y����Oaꢵ�J�z��S���]����ԛ���`*J_f�����<TKh���P��QDC�R�>o�� r?Cf�?<!�� ++�=Z��Fݫ�RO�ytː��@�����"�m�iAbX�i�P��=�>�ZI�JoK����_ғUւ���T�n� Zx֞�PA���r�M�K����a�F���2�<��(�B�!�q'�'� ��P+5(�|�O2�$(?��)��������m:t�]}ܫ��6��F���I%(� ++Q���`�/?���Wr�o�pGl�!��ˡ*�Ti�������n�~��<�3�F�<����,r��* ++�t*�=N���f�����#��A�����1#�ҭ�Ƿ��% ��9��ᡑQ���n_�1�_��E�l|m���l�A;�0|5r���;,�#kT�m�>��\�S�t\���di��!B�풘���P4�J�^�rb�m�뺚Znww� ����Y�&*4���K��]����]� ++�MSE�\�VK�4*������\��ˤu[��Q��6}���;�f���z������ݷ�,-&C��e�)M{Ԙ��i.J�C����l$�{���T��@Q�h4�,Z �u���i���n ʫՀ�����9(��v�&��<h�B��c�u��n�_Z7 ����7���N��0���� ++�V��j���O�F��Z���r ��u:�ߑ��(�b�*����(s=��@ � ܔVC���Az��J��t�^�pRA:��)�It� �\�^K���L�փ�\��B�\�ׂ��ڰ � �T�����*HO��%{V����Tl0�(��vr�qj�un�p� z� ��W|��t�V�O���4�-Su�0^m7��7 ++����,���#�x�x}�H)��ʋO/���(Lb%�����!O�Ѽ��B:�|�}[�aGb�XJ#�y!��[? ++Ȏǔ�|YmV�=���P�xh �9��$Iޥ����-M�`��s����[H\r�+��!�vDkԅW��D0)���� LJ/��jG��k>��w��؏��q�MR ��0|3ڲ�P��H��H��(}��yQR]�A>���:�3��C �Q�J�@�2��y0���M�`����ZQ��ik%e�)�Q��O�д�4���/�!�<�����xY1�VEW�hbX ��,���UQs��?���т���i ��P,��T�w� ++f*���ևL�cw��7syhA�el��\�L���?e��� $��Iϔ��-�6<u��Y���W0U�AٚdUiGZl�B�-0陴�!5��I�~&7�B"o�}�Bd`�2��.dd�DmY��<2ډ\��̅�������y A�I?h�N6ü�Fc>�&��1��1W��G�n)�N���7�����@�*?N�HI!�Լ��"�Ð�Ɋ_�����v��U��O��XBj��h8L�y�����7o���y ++�1���M&�'X���-�7 ���^�N�\������9���<<�x3������Չ�TʓKL�x�P�b�<PLSP�s�&.��&��Mρu�V�>�8Ae-x"z'�h�c�+c�կ ++�D?b�( ���|d���{*��oq�I�eFU<�����T�H"�!v"ʛ��6ڔ�Z�!d�y�픍-�Gˮ��UHm��FO�� ����(�E�XV#�(�[�a��vJ��hK�u��n����B��^�5TJɻ��z�Ev�Y W?!�z���;���V!:�z^�P���Ɵ.��Nd�(�D���K�Oh�OHE�\�����F2�t�tʨqΆh�ʾ�� �QL�%-&���d����� �=Y �y��gH�\�� +�g�2�S1#�%Lj����hg�Z�����il��ׯ;��q0RZm�ʪ*ǤP~�h^�k�ӄ�OTC�28�o�RҾɭ�s��UV��2k̘����V���㔔����gW�{w���(AWwwCC���y�_6m����А����f�ΝF���?�@�i\[[�zݺG�FE����{��`˗.E��X5)#,2�+ �(L2������Wr�RɥKƠ3cƌGy���?�q�'��|�!�v�������LJLl�{7a��M�����ݣG�eJ�����?�cGg�o~����1Z����`����>������w�}p�T��VS[������o��T\R���9���lG�D_^��4��ʓIʐ�ۯ��.CjÞ^�X��������~��]O?��l��訨�hjn���|z�ҹ�?�ӍQ�訨�����������RG�~��w/\���;i�_�x��n�d2�>�MӕUU����?�(22R���ʯ����RZ�?o��ߛ6�E��}{�s�Ikk ++�JJQx0�.E Gԅ���h8o�IE)SO��4��_�b�Z��_744��7~���j ++�x�����¥KG��t:�_�^z�꙳g�q#M���K���Z���ӧ���֮Y����5f2����=u����T����j����h>������3g�L�����?NIIa�3k�̬1c ++�M#�I*A�S�k��qJr��C��IN�B�������n���_|���2&3sLffbb�_�y�y�CzZ����ϝ?_QQa ++B?222�z��������s.P;>��{�����gW�|����:U��|�e˸q�(�z��ǀ�����ُ͙Ö'yԨ��t��W6�'T��3rR"yb7�Ak�|x�MP�IT��555]�r%"2�̙3e��{��]�v����O��iSSs�ĉ7��gM���������\.�?l�����mmm?~�7^��y�RSS���ח���}�ՃS�@PPPSs��//\��r�lv�����������#Gjh4Z����C�@3��3 ����P���l!��Q��>��uZ))"H�y^����3���3�ķ�nݶ����o۷M���J���_����������ҏ�����Z��o��������^G��3g������������s�'�DGE�}��w�{�`0,Y��]uUuuRRґcǎ;�\��鉎��|�n�MS�Ȗ4z+3O�ΣL̴�w�R���xO��������WAKk+C��1c + +-v��a6�###ىׯ_?r������/_f����?��#s�2<<��ŋ��3gΜ9sf͚5}�����5���� + +-F�ݵk�3f�@VV�Z�~�*;w����/���{pp�ȑ#;w�ܹsg�e�8?iI�����w�^�Dҷo�H���Ç:t����b��٧O�>z�hNN����W_}աCf�ܹs}}}'N��.Lč7&L����Y^^>���S�0`�������z�ڱc���c�q���ػw�Ν;ׯ_���9u����� &���ԫW��(���錌�L�{�� 4�0�y� +-�ԩ��Owtt�Vl��R3=|�pժUIII˖-8p ����/�v�������={ +-�B搗��h]U0s��ѣGWyon�ԩ�aн��K�����m�6r�H�B%� ���좢"���\dj߾��i�Z����~�f���������֯_?d��R���&������{����6l��h4�?��O>quu}�b#��s&��=��� � +-�&�7(LoP��p�NQTIi�V�%H�y�y��8.� +-����� ���u���,�����jN&��Ԫx��%���.5ӓÜ^K�0WC�8. +-��7~�C�*���&�7(LoP�ޠ0!�AaBx��� � +-�&�7(Lol�k�\W�ө�f�8ʻM,��)�r{���Fovn���D"��D��]��d��ۻ��nd�v8�);7]g(�k�ږ�F���{)����9�V��hJP�j�&�ڨ5E:��z�y>NaҖI$2��T[R��\W�yu.a2���<�F�$���B�ޠ0!�AaBx��� � +-�&�7\n��tj�^�{Q��N�S+�W�V3=�/o�]f��,��I��W(�����僑j(+�o[VG�LoP�ޠ0!�AaBx��� � +-�&�7(LoP�ޠ��S�F/�#t�� �ыT(LoP�ޠ0!�AaBx��� � +-�&�7(LoЍ^�)t���ы���E�&�7(LoP�ޠ0!��i�0��[0��~�U��B-榠<�@,x:�D��R,W��I�MA{�����̈a��*>�`��b���< f/'٫�So�p�W�V�S�*���,=f&hw%��S�� T1��5L�*DЫ5�#i=]mĶ^��F��H�HL��b!4�Z�vbpU�Ez������r�XG:��s��� +-(5���b�.���myZLc)� Zo��b�A +-���2��Ba>tF �$���t���Ӟ����-����р���\i��@.�J����&�A!)�,�",����_�I��cOg�bNRh�I�h��|-桤sԘP@�u��$F�8� X��"Z!� +-u�� ��H��<��;X�<���d�č�ٕ��l��F��_�P�S7���"�0���$O����/��N�X@��EE�P@;HA`ua�LMcM�4��?��� 1Ep��^P3����)Hp�BL,xR,`"1���0Z&����P�� �@$�4��� $B�8�p�Sy��F� )��i@*��I�b��d����1���dB��)���L$MP���i� +-i�i3� �BaI�ؼ�D�F�Ve�>�2o��9y���:�0iu�G�͚t����'�z���v'-$�������N�ғ�х|��U���+�|�*��Q�r�T8�ۻ����z��=�Y�����[ػJ��j�N�h��?�.?|�?�"�N +-�|�"MMOtrp�$�mX�{jM���f8��|2�\�,3˅(L�����2i'����4Ec��4�-�i!F˄�TD)��RDR�`EzQ�Qd 8Fۋ G1!�2i/&�&a�QTj��J!%�"����r�f�OG����,�*E�/�%{8;��jh�^p��t�A�\��Δ[.�w��@'�; Yn����I�I��BJO���*�D��4�i%�P�Δ].��JS�V�� +-s�N�NRK�Q�e"��� +-q��p�p�e&!�x���z1��R�r�m*��Z)�x+L�: ����E1�(D����o��h����NL����&7����4���x�uO�RYo�-���ƕ"Rk����RjYO㔙�@�����[��6����v�1����j�)Lb ]�Dx��� � +-�&�7(LoP��T���'G�DQ�N�4]�cÄ�������BRq*M��=+z����QEĘ^s��w��+tPCx��� � +-�&�7(LoP�ޠ0!�AaBx��� �M�aB��ʘs� F�ǡ���G��'�p�ʞ�p��^�fBG7�3T!�AaBx��� � +-�&�7(LoP�ޠ0!�AaBx�O�����Ν�����%/_��z�j�|;�; �?a"�ܹsf���K���F�Q ���d���:D������ի��cǎU^������|��y�T����9s�킼� +-~��M�6=����O�:�l6y��r���,X��������R)��T�n�=z����۴i�N�X,۶m���_�v�:c��\�F����LE���9R&��������8^�^�|������Hddd@@@���O�8q�ر֭[Ϙ1�����~Vbb�P������y���t���h�>{������߿߭[��c�zxxܽ{��O?�{{�6mڌ;��ߟ���fjժ�ĉ��999aaa�V�rrrb��ڵ�y!�۵k��?���?�,Y¼�FQ�;��^��<��_~)**���>|����ۧO�NQԂCBBD"�o������&M����9s��j�͛goo?|�p��(*66���?�iZ �_/����w�f�V>s8u�T\\\����w�>{��i�\]]����^��̊���0,!!a ���2�����=L���;vd^'%%@�^�ؿ�3g�TX>::��ӳW�^S�N�x��,�RݨQ#΅y�v��Ѷm[v�Y�^�x���{PP��<y��+W�dgg�]�V,�S�0d2�R���\Ά&##�y���������|�����j��j�rss��Q�����k�Θ1�ʕ+��������رc>>>�P�~}����0S*�"��9�9g�s�P(���iРA�\�v���?���L&�5k��ɓ��/^����ر���/%ycccw��=i�$���%==�������l.--MII�֭�X,&�9��D��/,,���|}}��$11�{��U~�N�KOO�������ӭ�(*""bڴiL�222j�$I�V��a������"44�±��pp�X,ǎsqq���/333+/��_M�6 ����aÆ͛7oyrr�-[�M��r�J�Ba{I�<��6g��PH���` ��b��z����233{��ٳg�m۶1�,Xp�ʕ����Μ9�Y���ӭ[���۶m�m۶�g�Ι3g֬Y����ӧOk4�>}��F�Ţ��F#� S�|�Q���/^�x�ҥ#G����OW�^��m��={�dggGGG�����/�����ܛ7oN�2��յ�w�^�x�q�:�]t�ڵ���3ft��%--mڴi�/_ff�D"__���R�(++�H$NNN~~~*���(___�J5�|vS"�H"�8::����*�J�����J$77�*?Z�P4i�D"��o�^�T��河�m�v�ڵ=z̝;7))i̘1���KOO/--�q\�R�ܹ�zSb�X&�5hРS�N��7�o��0���mܸq���^^^���o߾�̙3��駟�]���Zm++���˗/gߞ:u��¼y=z�P��iӦ۷o�֭������7�6l���Nj��N�<,�z��m0����/==�{��sF�Q���<y�cǎJ�2))�O�>�\�٬V��F��`P��f�y�ƍׯ_���?q�\�VQRRr���H�7o�С���4h��'�,_�<99��Ç�nݲ��NW^^���ߢE����V����ܺu�̙3�����H$Z�hє)S�ϟ���Μ.4mڴI�&� �J����-̞={Ĉ�����7��T+YYY�y���� ++>ڶ�u��BC-V�_���� �DFFΚ5����w��o��&�)4$������;::�]˕�W�N����O���O�9�"23 + +-F��\���T���{��]�x1A]�v f�Z�nݺu�|||z��ɜ<���O�:��{�ҥY�f1�8�gϞ>}�8p��իM�6���ttt,,,T�TÆ svv�\�3f���lܸ�ѣG�ڵ[�f ;�gϞ2����?$$�YG��:Sjjj�&M4hгgO�Y����ϟwrrb��{�� 6,..���-srзo_Υ�����Ə���w�i� ��8>nܸ�ӽ�����ϟ?ϽP@rrr``�;�$��vJvvvNN��yyy�:l1��M&�-?Dk�nݺu���m�����i0�L�"�ɚ6mZ���̘1cd2Y˖-[�l�o����9A4M�r��y8�L���T��^E�&�7(LoP�ޠ0!���LGh=�rKw��*��&���K���ɏ���q\(*Jg'g�O�r SX�ٖtn��TOE�)sIY��h���m#�0���K�7���~���G����I� +-p��Ύε�jq���)R:�!�AaBx��� � +-�&�7(LoP�ޠ0!�AaBx��� � +-�&�7(LoP�ޠ0!�AaBx�O�N�<���??g�����o?~�~�z�/���+��j+(//����)�z�#�?��H�����>}�<�k؇���o���{�������4���������ݏ=��{�U���j7m�t���)S�L�4��n�����i��W�%LA�T*�)L/�QQQ�{���ުU�ʝ臘�2�4�9���4ӷoߢ�� +-��3���D"a�J���Z�f��{��3g�� +-+9r�b���.V#��@<\�d0�QS�8p��X�/^�j�999���%%%)))$IΘ1c � [�l�p�B��1�M��t�[�*W�^ݺu+�://���%**�Y�fU�C�|��Ç9��K*//߲eK\\\@@�W_}U���vB���췱x��?�8$$$//oǎLO����g�>r�H� �3ϕ+W:w�L�d��xh�>t�О={����O�^���^�z1]���}��6mZMⱳ�ck�'N���A��/��ի���ÇgDž�u�;�ş�ɼضm�3?����kϞ=͛7g�֭[�y��eee�V����;t�R��;6aڵk���+�رC ̟?_�ղ������Ύ��+V4o�<***55���j�z���L��̀�p�֭��t___�4Nګē��t�ȑ������)S���Ʋ�B�dii�Ν;�!�����G�Y�j�?��v +-+�mۖ����ѱcG�J�u�֜���������^��E�C�Y�hQӦMG��n�iӦr��Ν;K�,qttd��quu���C��<yr�~��!�XW�^�;w���o��������1���������/%%%>>>� 8s振��G������_u �$qwpp���'I�:�z���ԩ����|�����9�^�aÆU�V�[��z��f͚EGG���L�>�BU�pqq�www�/^WW� +-� �f�:u��g�}֦M�M�6������Ϛ5k֭[w���iӦU�p�u���`����rrr������>}��^���/d~��7]�t c����9r�`0��� 6�zG���Z�nݽ{w�Z�2�nݺ~��3f̈�����/�Qu���짟~���ر��� +-��j�F�.߮]��m�Ξ={���oz ��BBBN�:����~�zv����W�\�~�z���Νk�璚�:u�Tf���X,f����Yׯ_��̌��Z�h��\�z���~�T.��`x������������|���Ç��ʎ?n=7<<|���111:�n����DWW�>���?�8t�P���_u ���4�Z�V�SSS�Ǵuss۽{�ѣG�������f��C�-Z$��� +-�СC�^�n݂��ݻw�[��������h4B��Ν;���;{��D"�Сsm);;��~KJJ�ddggWO�P2���u�������˗3�kTp��]�$�����]�63L^۶m�k=�91�.]�=z��8iҤ�}�2�.��G"������ׯ��t��9��߿���:u�С�_|q��Mv�/�@��R�N�N�:=x�����g�qrrR�T�n���o�M��b�P�����c���۰aÑ#G���~��w+W�lӦM]��Օ�I x{{w��]&��?��s\�d �:{�I* +-[�j�g�fzvvvHHȺu��O�����֭[GEE1���E������^�z�~��.\`NѢ��:u�DQTbbb�M&SLL���-Z���T�{`�����@<�ϟ���`0��( +-�k�l�R��feeI�R�V�e˖�c����L7�yyy�������@<�ƍ����<��YYY���V�����p�r�ԩ�&M:t(�a{��0�������s������izڴi� ��5k*���ё���/___�x��a�}m�~��H$���֯_����Ç������� v���ƍ˖-+..:t��/ǙK.ܿ�@<_~��O?���g�9;;/X���ߟ��K�.�w�e�R����o���w kw�܉x!�v�� �IDAT��HJJjذ�ڶm[��`�1ocbbV�\5eʔE�����Y������O�8Qe��_R���?w�\���"##>|�.^�o �C�tff�C�8��'�,^���_�8qb߾}?��f͚U�#��阘�ؼy��˗3���e��{W�(����ē�����ڭ[�]�v1�M�N�����/������ׯ�ƍ���X����u��3g�lذ���ףG����%K����Ν;�N�:�ԑQ�����)++���~���;:&�e gg炂�O>��cǎֳ|}}W�Z�p�����;w�ԯ__$mܸ�`0̙3�رc8�>|�z�����z������u�5k$i�^�M�'N���2e��[C^��9��i~�m�:ȥ�x�� ���U+�IK�7(LoP�ޠ0!�AaBx���EQ%�%Z�� �2�f�e .י�r�*?���2� ă�}\j�'�9�� �a���q\(*�o�0� UB�9�7(LoP�ޠ0!�AaBx��� � +-�&�7(LoP�ޠ0!�AaBx��� �M-b�ue:��lF����b���I!��������tMy�D,�$6y�,�ɤ��w���Ȗ�pSvn��P���Mtj�����R�l��s&�^�є�$�0M�Qk�t:5�-p +-��L"�؉=R�I%�r]�չ��l6��I$���s +-]@x��� � +-�&�7(LoP��p�ѫө�z͋�C�5:�Z�p�:���]�y6��r�� +-{�¾Nm?[>������eut΄�� � +-�&�7(LoP�ޠ0!�AaBx��� � �ы<�n�"<B7z���Hu��� � +-�&�7(LoP�ޠ0!�AaBx���������@�<J�B!��j���B��uT9�0!I��RLf� �`�;i�R�p����*�*"���U�YD��3�VB�����T��X(�)&���P��ZJ�NB�R��z�6��%d���������H�M�S@�W(�8 +-����pz��7�{S��Q�RF�S�i����QC����`�� +-=���p���p�]J�B�A)�/'5��AL��h�! �@��1_�����,����̷'�("�����,����2e���RLa���RN��@��������\z۽�w�V��p������F����4 ���=��h��������fa��L!h��������b@�{J�%�Q��J��O�}Rh���pOi���l��F�S<�À���=�Ӫ>��h��0À��7Ŭ�̭��6F3K�XhS.q�K�N��宫�7z]�<�}0R})����:��Ѝ^��@aBx��� � +-�&�7(Lo��I,�Z,&ދ��uf�і!���I�p4��?���f�B�f��)��.������H5��������1zk{7�ν��zYg)�q;��0�~�-�g-F�Q/��Kέ�M�W���DjI�b�t������<�1z@�S+w��F.%)�001I����f����Z��D4��I�KH +-�B\F0/0A[�"pLHU�^؛�B��HH�ޔ^�� ʺxQ4�P�W��I��ς�vEv�5uOo{{6��Ʀ0!�5ti�� +-�&�7(LoP�ޠ0!�AaBxS1L��D8�&�zƥ~���5Ä�������BRq*Ӹ�Y�C���*"Ƭ�K����_Ѡ��&�7(LoP�ޠ0!�AaBx��� � +-�&�7(Lo��=�T��������8���R������C^ٳB��C^���L��p��!�7(LoP�ޠ0!�AaBx��� � +-�&�7(Lo�\�N�8���#��%K~��w~?���d�ҥyyy�nyIG(X�t�'��L�=6l���.** +- ���|||� 55��ɓw�����=<<\\\� 11q�ĉ/,��={�7o^a��l>q���ѣ9�b;�a����������Z��Ν�W�^�.]������h�c<x�e�ط���"��y���@.�[o� �V��w�;�����ܹ��h؉u��urrⴋȫ�&oo���h4+V� a�����ԩS� �^�����={vYYMӱ���O�1bDHH�����9rԨQ�oݺ�X,f^�X�B�TΚ5�rrssǎ[a�%K��nݺ�]�v�wyy�ϙ�F���� Cnn����U*UFF��bٷo�P���>|��ۻw��;v����"""fϞ}���.,^�x�ĉ 4x���f�T�����ũT*�JŜ�9r�y{��U�{�p��f�������f͚�j�*??�Ν�-�(��ˋ]�ƍ��}۶m�3�[����4�������nѢ����+lY��dgg3����E"э7ع�����y��I*�~���Ç��� ++�L��r�&=��ð~����������ڥ ++xgf��$%�ϳd��~��!%�F��ƽ�� �IDATdWŴ�Ip�Z���^3�L���Y�b� ������\�z��[����9z4����]���-[6��'�UU���/�[���N�4)3#��w�eǟ��t��������˖]�~=((H���F�����0��Gm6��ӧ'%&J3P|�RC*���gIiA�ɒώ��y����ccci�Ow����1a���}��?������K�~��m����_���X�t�رcQ����.[�g���yy͘�����t:���ޝ�����oWVV9vl��e�x��g_|���t��I�����~��U+Wr��)��vi�}��U�p�W%�k��іCA�35c���O��u�����_���n�{�ҥE���z����===�%%��g���55���m����y� ��V�ؽg�������;;;o���N�����f����}�����ƍ�-���^�z����/�����X���g΄��777765M������'�s�;Z Y���JE ++o��zWḛPF�x�w��ǎKMK���8�|pppzz��VVU-/,LOK+--�YV6b���g���kشiӖ=�LOo�m�6������� ���������ޟ����%K?�'�O_y��Ν��Ч-Z���"햴��݂ϫ4�,p�<��n����� ��B�<Pɮ�Bh&����p�g,P����� ++A ++��BȢ�$���\9�*¼7��bb�b���W�>�0�4�M;��H6�-��d|Q6�+Hwl���Vw���<G^�ZL< �#4o���� M,�wF�7��"���O�5��80�NK������.a�\���D�<�*���I]��U~X����>����L{1J� �� �/���g���y���JBwI����Q���JܓQ ++F�Ȓ�����-�p�N �b������x�����m&�-*��ꍪ�Y@�^����}�3%�� �O#K��2tF��_�ƈV�1����6�HIv�O�D�xY>��_�:��Ð�(�vE#�¦���n�M$��p� �jl�ܑX��hK�$�B-N��q2� ++)�~�q����dl���?{���֫�\�}�O8�w�Lp�� sx��O>1��.[HLJ��-�ꐭ�;ދd��)����6��%�ᙞ����7��H��W*������!8��,'�� ++�S�*�@�"��A;G,'�0t 0�J"� ++��S�v5LK���4ՈT����ay@�&�j��>U��m*���R�k���3��y�R�N���"2��&��j�Č��L�m��3z� �@m-��+ΐ��Hu= � �zp������H�[�O�L]��\�Kt�[t���K�'{ݔ'$d�����vg�#��'7�dO�F���5������T$j�W2ʑW5�lؒ, Et�����_}K���0!���H)����B��#N=˦t�Vo)�p����Z$��^�SL/��E�zT��Fg�%نS�c�"������2ov�{���Q��X9�(�w+S�ΗN�����x����-������#X? ��Σ@M+��t8� 0ctEt������p�KSд��E�at��zA�yu��Wtm��EQx�������ǧ�D��l��/� ++�%~��c ++p���˧ކ�X�u&�dkdr�J���| U�}��SK�ᗺa�|A�)�*4"aR�\ձ��щ��� �� ��]�:y~�2���� ++BbH�m}��D�:���B��6��C�Û|�QT��J�� ++T�䨊���* ` ;Q���|��N�Õ!��x�/��$����\��T8����8�:9C}�²��\>%ݭb�e� �n��0}��U��PH��71 ԵC>�2 R�iA���0�~ JAy��)��T^F����Aߖ<�x��ǣ���I��!��,(1��<�RE��������<)L�͟�W�h��~ԋ�g��O��cn����W2t��� ++�J�p�bȋ�`�Q?j��g�h/I�D��'��u���~�~�x�������E:OI�BPv��:Q�d�A����,��'58i�Þ�s���^���H���*�q�I� ��j?�� ++u���� ++�a�){nZ��/�0h4��J[t�N��M\�������3/х�����le�������֖���>�흀S`ggg||<j�� 4�x��_�'������t�pϗ�aD��X���̓�xJ[t�}��$��|��D7�guuu{{;�=|�����͛7��⋱��mmm����/��0�͝���P[[���߮\�2$$�C||<�����6���Ge�hnn~���_{�5��nݺUSSÖ*>>>��id !�wپ&^��(5����Je~�Q�5;�M�G�qé����W���ݡ�4���~�36f�5�Luuuw�����������:y��eˊ��ƌ�h����8t�PTT��h����ꫯ��j�6lÆ (YRR�Ν;M&ӢE������M�� 11��}��V�MMMmhh0�Lw��)++c$�h4O=�TTT��`C�9������6v�X����&�)##(�����Ԕ������ܹCQ��ѣQ⾾������Ԑ����:���aaaIII:��+//�y�faa������;�Ð�Ϯk�Y�hip����M�g�&;��I�&i4�պx������z��p�Ɩ���������z+;;{���(}hh��~��O?��l6?��ӱ��'N�`+����5k�:t�f�mذ��v�����'/��RHH�ǎ{��M�^�`��o�������woFF�ȑ#{zz����7����{�쩪�2YYY�w�F�'�|���JSS���s�Nw��Ɏ��W^y�0���.\X�v��Q�N�8a2�bbbL&��l^�zu||<*�֭[cƌ��I��O�|C!z-�h������vF�jǏМ�u���<��[[[G�����Z��رc���Z�� �a��ɑ��---��� N����8##���t߾}�&Mjnn6�L������#G�t8���k�����/���}��(jÆ �p�ƍ���Œ��������7cƌ�W������b�K�\s��MNN>��:&_�5�JIIIGG���f�����Φi��͛�[&L�3g�|��%%%,����]SS3o�<��{�n[[�ȑ#������U�� O��������4�4���H��A▖��}���q����vd���Ĝ<y2;;[�����!ˬ��U��}���5>>����Z��o��h4���]��3gΜ93::����ӦM;y�dZZ�F�9}��ȑ#Q����3g�,..���������z�hllLLLT�j!***<<��VEEECCôi�nܸ�����|����=���Ç�d���eee������AAA덦i�Á�t���>...44�������IIIG�Y�dIzz:�E���s�h�� ++�R4 n������]__���YUUy���9s��;55���{ԨQ|��O~� &dff���}�����?�䓞��g�y&!!���V��(j�ĉ���ۻw/��t���.�Ѹ{��ѣG���S�2�[��EDDļ���ӧO;���J�|���b����ϟ�6�>�������N���UTTd�Xn9aӧO3�JJJJKKm6[XX�<�.VVV�����255����j�"��� "���?~{��Q�냋�wϻ6�wu�=�EJ_\\L�� ���Ν;���u��E����ڪ���k�X�n�j0rss5��ի�M�v�ڵw�y�ҥK�@`0��Ac4/\�`�� + +-1bD|||HHH�V������H�lѢE�z�<8m�4�c2����� ++�G�z���ޞ]��n��7n���/����Р� �������p�����R��X,�������N�:�-Z�ti�f�D"��_=bĈA�Y/ӪU��;w�ܹ�e˖�}�YAA��3g<h4���kժ�f͚����G� �W���`������J�Eu��}ժUݻwg6(��k��ٳg[�]�t�-;�pfS���9�]�v�S�Nnnn�$11qܸq�8�_�tiÆ S�Lٻwobb�;wZ�n=b�ggg��5k��ӧ�=ڭ[7�0���������:��v���[�� +-�����ĉ���ȑ# 99yԨQ��6��a:|�p���w��x��]WW���̄�v�[�n15��?�ܧO�q��ծ];00������Y�b�{����^�z��۷o����a2�A(�Jv��Y���u묬,���Ŧ0ݹs����ǏoԨQ\\��ӧ'N���颢�����,���9iҤΝ;7l�P �?W�~��wOOOf�ѣGcƴy(,,�S�3���cǎ�1��LP^^�OǑ�S����y��ݻwW8�"o�K����|�͘1c�ԩ3jԨǏ��^�z���РA�q���}̘1���111�V�z�fSRR�4i¼���IJJ������e�X�"�ĉ +-ň#222� �y�qӥK��r�_|���ܹs���R����nذal�?~�w�ޱc�n߾��ՕiMu���{�`N���\�z�q��E����aaa^^^�э�餤����?�j����S�����333QSҷ��an���&L`�O����������t�۷o����3������N��߿��E�6l��8S�L�2��6�b�����իcbb����=z��������h�"�Eii�J�JHH8qℿ���m�rss������\]]۵kW�N777;;�� 6lhӸ����8��ҥK==='O�\a:I�}�Qnnn� �ϟߦM��*��h4���W_}�����[��nݺm۶&��ڵkݺu����D� 8���tiiiA8::6jԈ=��<yr���;w��Ě�����>x� 33377�ѣGQQQ���vy%����zO)���j��a���V�b ��%�&�7(LoP�ޠ0!�AaBx��� � +-�&�7(LoP�ޠ0!�AaBx��Ʀ�)f=��D�#�e��q�F�ڭ�b9z�迈{�T�F^�jxp�R^@�f �P^@=�d���P�FV��{�[y@RRҞ={��)���[�nez�9y�ddd$�#��K�a*H#S��Is�H3�7W�������B��j�������:�."""...�̒EEE�?��Fi2����ٳL�[P���w��ň��ߘ�~��G�o��aά���fz��O4M����X[����ݻw����3g���b`�������=-��/Z���*�JשS��Ǐ߸qc�رݻw/++#�4 I��t�ƥf�N"*�I��K��WJ����mQQQJJJaaa~~~JJJ@@��������/��C�FFF2I�Rzz:AL/+�s��q(u���2a���˗/W�����#G� $$�yAQԚ5k/^Lđ#G�eW�Z�T��+W�t�ܹs�ΫW�nܸq�&M +-Ŕ)S���� 11�����\�T|��!L$��^�������������Kpp�V��ř������PXXx��� +-]�Up��I��~�)::z͚5��j�*�{�C��M�6mʔ)K�.]�dI~~��\�Z�x��������~��Y�ڳg�ݻw.\�|������k�.�H�v�Zf��bcc���7o�ܪU��/�;�U�V�=jԨ�t����?�����\~.ab~�����Rl=ˣ�X�WX����R����'O��R����sss{��u�����̝;w���{��Ι��L�� +-����C�{yy8::J$�{���r(����Բe�V�Z5nܸ��/^��[RR���������n�uǙ3g8�z�j�s�Xlggggg�P(�^�222�7o�T*'M�t��1�;v����{���t� ��\�¹�6]��qw��N����J��S~�'�W a�����U�Edddǎ+,�~�z???�Bq��MOOϴ���]���Y��������k���\�L��&00pڴiL�qqqW�\�ڵ���S{������g&&&&2}\ ��K�.@tt��ѣ������^&00�s���Lr�'kY���V��-%M�~=�w��j��b�$�z}rr������٣R�۵k�`����I�&M�̚5kȐ!1114M�;w�M�6J^�Y7�ܾ4<<|���111:�n�����K�.���?x�� �}���z�jBB��͛G�ʹ�?}�t�֭@��8p�~��S�L����ӧ���˗U*U���^ ��ɥ����IbLZ��M�1�b9vy�Z_BY/ƾ>u�Ժu늋�7nl����իW�o/^l�#4�t����rss+**Z�tiLL�J�Z�|9��Wsl�V�?��?�½K�.G�e^O�<�o߾2�lժUm۶e:�b�X,w��I.�gee��f�D�������2dHbbb۶m[�l ����f�ڼy��_mK����vk����IK]�R�0i�^-��v�������/\����ؤI����I�&���6k�鐐�.]�1����k�.�[�D�����9244t��l�_5I�6mBCCo�T*ccc����QQQ�:u�(*11�w��&�)&&�w���*Lw�]�tiѢ��ݻ��@,�^�7��ׯ_�X,��x�"[�h�"11�0�ǬǏ�ٳgĈL�8�&�k(I9nf���u� ð��b�L͛7oyRR��8ިQ�S�N������[�Pܻw/33sŊ�� +-�����UTTԭ[�����С�{;w�̡�՟\.߸qcDD��`���(*99�aÆ�:u�q�Ʋeˊ���:b��1�6m�СC��������999u��a۶mNNN���S�Nen߾=��h4^�v-!!��_���{��ec�9v\�i���L�/���4P��+��JDD����ĉ-�֭[���/�JG�����T*#""����W�\ٿ�֭[woĈ�WSPP0n�8�Z-�Hv��Ş�"�WVV6~��Ç[��͛7o�С?��s]{����Hc�a�W��ˆ�y��j7m�t��A����O��� +-cZ�@ZZ&f��\��7��\����2���*w��;����Z�������;|������?>>>~���͚5���trrZ�`A��Wd�4s��͛7w��144��ٹ��tѢEׯ_���P�� +-�^��ׯ_�Z��,Y���3f���-[�m۶nݺ�PVV�o߾G��X���R��֭[7nܸ���{ذa�,��|�ȑ��W�̐�� ��%�λ�i��IK��wZ� +-�NCaBx��� � +-�&�7(LoP�ޠ0!���pL�^�&H�+)��ىl�G�oO�<y�p��w�J7m%\���1� 3���|Q�馍�T����4�q�ƢE���������yyy�������o�=���̾MHHعs'T�Go�y���]ɑ���Tyf6I��2OAL�:��?���������r�=�̙3���7nܘ2eJFF|ժU���$Inٲ���c�Kz}�ù�`z���1xn�p�c�����o�...fڟdff�����b��Ν���b� +-�9�O?����,�h4���G2O���ŕ����S9P�TW�\ٰa����kժU�y���3\�$�v�_u�È�0v<E�4�l^�f���b������������˗/;99���_����۷ХK���$�$�ð�ӧ�h�B��N�4�{��L�V�Z͟??77�[�n�C�5�s��/Z�(((h߾}�_]uk��\����7L��6��Qc`� ,�b�������>}��a} ==���p��e�ɄB�X�l�̞=�h4�ݻw��÷n�*�H�@*�B��4���P*��'Og;�:�����o�~���+V��U�3�,�i�y�f�yxhh��d���^�v��u��������͛�����i1�T*����}�]NNN�Z����K���n��$I$�?���� F��]�@�Z��<<<>\�n]�Px�ԩ��;w�����juvv6��B???��s����_�b�`����<�mBXPPp����˗�d�!C��:u� �<<::�B�p�X���� ���ǎ۲e���� +-�í�-��. ��+X,pp?�|����A�]���IO����cbb<<<�߿��}f +-EQ 6d�����4:hܸqTTTVV��{SJJ +-��u�Z���=�yxQQ���+�����%==��^���s ��1t��V3h�9n�Xխg233��a�w�9s�@�v�T*թS�~�駌���c�Z/f�־}��6m�a���7������t�Қ5k6o��tQ�L�ӧ�ʕ+�fsrr��ѣO�8���z��i�G�y�����ôLd���=�s����l�����(���dc����4�t%ؤI�;v0g?W�\�1cƀ*/�vڴv��}��͜9sԨQ5���4gZ��LV\\̜�@5k���Ѿ=-��kҕ�p���Z,!�i9j����gϞ]�v-I����^�aÆ��`���$''�߿ٲeܰa�k��iӦMJJ�͛7322bcc�t��QQQw��qss���~�������Ǐ�x��3���eeegϞe��'%%Y7g.�T���\a�Pr���KMÿ��0sЇ�o��������7�O�>���cǎuttLHH���ƍ{��q�ܹ�K�Λ7o���m۶�6m��`�7o�H$z�Z��4o֬ق֭[�s��O>��k�+����w�O�|�K�A��Ne�]�Ҳe���p��������p������[/l6�7m�t�ܹ�۷ϙ3���d����bnn�ĉǍ��u���h��7z/\�0s���?�|�ԩb�X�������}� rss]]]��;25�^� )))quu������7n\�Z��,� ���Ȑ�d����dž��O�i�ÍF��˗{��y������H��ٳg���_���ڵ+::����AAA)))?��������O�:���?߾}��͆�����#/�M��---ݸqc�^�ڶmk�IYQQQbbbBB��ٳ +-��۷�Nh�����h4:��$I�@ �D"�D"������3�_իy8�NCOq �AaBx��� � +-�&�7(LoP�ޠ0!�AaBx��� � +-�&�76��+ו�tj���Wi��B,��)�r{���y���tMy�D,�$/^��,�ɤ��w���Ȗ�pSvn��P�װ�-��T+���R�l��s&�^�є�$�0M�Qk�t���,�¤-�HГ�5�T"/וq^�K��f#:O��D"�-?�Х�7(LoP�ޠ0!�AaBx���˽9�N��kx/ +-���tj����j�� �6��r�� +-{�¾N�*��D�iY��x�gC�LoP�ޠ0!�AaBx�S�:}q&��KQ��'�DS@Z�=:�&������鵫�a2ii`fu9��"IDAT��6ryY��0�������{s�GJ��K,Y��vY�;to�H���4��킼н����4� +-JSF���� ݛ{c9-a")fԠӦ應9�%�I���^5?Lf=-�@&��.JMW��DS@�h\�a0�Q��z��0���P +-� �s������1���P���z��0i)�����o�45] s��"̬C5��U��d*�q��E`�A�ת�ߛ+�w!)�VG��&�>��)�#�v��/to�y��>��pE�l��?�ݛ{��A�,I�()e/��U��н��1�i���k#���:��0=�hN����>�H $`�<{"����5���'��\b~��Ҩ��~sg\&--�<�0�����dk͔}�~�?���+�����2ki\���@���ѥ����0�ܰ��byɄ�)���7�~ͤ�§5.��L���a�0L���|<�C�0�V����7�?j�Ҹ�ú8��FO��[l ��rn� L�)�p� +-,����L�� +-��b̄�xm��I,�Z,O���N����ܲH�O>Hb���~�0Q��=����3�i&�,/��������������h��\~�)�%%�O�` w��!=�=��Ga*����$vX��4���8 -t�I��'^���9��ut� ��!�+��XݎBw?����(�&�sm,,yH��28���,�;��P�M���`�.}����?,1�p��<p�H�ic9�R_(��ߨfm��J��1�4ph�Lf�@��S� +-�Zpo�c4<��8��yT�{Z��I�6��fS9M�h�%=m1�1&���r�0��":�6Q�C9x?��4y�W�wK!����f �4M�H�U��̽E��1;��u4IB�����M�!=�\�7�t�"Ia�J銫sH�Z���k�JWB�y�4�RZ��B(� ������B*?����n����N����8���&�����ń E c5�\Wذ�H,�҇TQ&E��K�K���+�s�-�y�:��1�3�+�|���bZ�GzJ���[ +-�����/��9�YK��8DMӘ��"̤�3��X���#�4a�p�./���j��� -���*/� 3H�@j��p�U�������)�ky5��-���Sk +--7<%��.��Lr�HN�ĄILYp\HQf��-u�K��0`@� ��b%i�&�#,:�HAPjBD���AnJ�^H�H��NHZ(7[��Rp��i��0��I�T+��p� B(!p �X�BB#pw|do̓K,B�Z{���� aĴ�m'&f��@,���H(�2�@k�2��LK�Ydʫ�=���Z&J��J�z��D��z;�+E�p���K�T'��I��J,BM��f����J<t��I�q�R�SH���<G*ODp���̸TB�0���h��B�ċ����#[��LeB@@����2f1)�b1���(�i�0DJBlo�?�`@��Ae�$ l ��tj������)���H@[����� p ��8MZ/O`!m�3.SF� A$��� �sZ�����n���B��.R&�0 +-�d9���P@�*;�i�������_��8T�{j��"J_�̘\L�����0����A� #��`��fS����&������c��� �����&�V�o�"o +-�&�7(LoP�ޠ0!�AaBxS1L��b�( +-=����MW�xE�0�8:�!/�T�J�4�aϊ���xT1f��\*�����ޠ0!�AaBx��� �����N�؟4[����IEND�B`� +\ No newline at end of file ++�N�{��g̘�T]^^��o^�t ����r��!�Ñ��M�dٮ��dl|��7���:�����n����^�~���199����jkk)CBBRSSoܸq��-NӲ��[���ϧ���ر�QYY�l�������-[�444H�*輂dgM���n�Z�f���ҩ����|ӓ�L���^F ><##�ܹs3f�0v���ѣ.���ବ�;w�M7����z��b�X,&���А��v� ��h��TUU������������{ꩧ���EM�4�ԩSl//`a2����Ξ=k6�-KQQ�ȑ#���KJJ�N'��5 ++%���9t�P|||tt4�����aÆQ��j�l�b2�L&�^�G!�����7^�zu߾}s�������Ġ���=�XQa�sx�X�w��C��0zy� ��ϟ����~geeEFFZ�V�ٜ���p8���P����iӦ566>�������G����WYYi���չ\�K�.9�������f�N��j�V��jEO��ruuu�����ֶ��lٲ�"""��1�A��v�{{{-������v��q�� �Ųr��u�֭[�nƌQQQ+W�|�G� Y�r%�34zN�8�S���0�L���+..��� g�Z��|���d�2eJRRv"�l��W8��/f:~�u����f�����ÎP�ZXX��Ƅ���g�.]���/����=w�ܚ5kv��=e����ĉoݺ���3eʔ������1cƜ<y�]���.**���y���[[[������/_�\PP��Ci4��������`08��9o���#G�>�믿NMM���1�a����y����[oM�>=;;���(==� �q�Ђ�C�ӽ��ޞJIIIIIIHHHJJʪU����� ++y�4Mwvv;v�"##-Z�[��N����JN�+��?���Ξ��aG^��;w�@����n�F�,QD�@AA��ѣ�ܹs���3fܽ{���}�ԩ/^LLL���EtzzzFF��dz���G���O^�v��ٳs�̹{���ݻ���W�Xa�Zi�F�B���Y�>�쳌��%K���o���,,,LII��t�f/��(��������^}�U����Z�K#f��(�3d0P-��L�2V\hС�Jb==�)�b���<...>>���F�����_�z���=???..������%22��� ++/Czz��)S�f�s�fϞ}���������-�Ν;'O������B����|�'4�����/F���O#�uU�y�4�̞]�r������ c�L�y�@�4�� �5|2�]���^O t��i !T_(��.��~_1���8���+d|�ʛv����(����ŋj=q�����idżT��L�!C�bYᨂ�.���� 1,�{�P&u�*�B�>"�h�)�^��8��n�*��|��EKS�8@�bH2�}]�wJ��t��Z�v��T���e����t�r�WN��-������+��� ++�\_��J8��(��z���$�+y��e�@�&U(O��S剨�aȫ ߧ~Pi��x�R���!�[��#�v窌�B���;~URvy������ _⟇��y�y����Mu�D-H�j��sNƄ ++�h�ScH�J|X��B�ԭZnyu��jH�,�C��Z���jQ�&o�B�,\�GN�������N�������o+���Ę&���2��?u����}�2(���yo�,H_,[�`H���h�i狙_;��S��|Q�8�0��U�aW��Ì�����#��P=~UꕴfB����B��7$�S�ڑ@�*ѻ*�y�Jȧ�Z���-���4��-��z�"v/�| ++i'z]��8SB�|����y��p�U8��G}VB���V���V��2L����?�Sj�%�@�Ð1Gی��Ps�������dH�EM^ AaRŒ��SE?Cݵ��@��G��;xAӴ-R_�>����[A�H��� �S����M&��v�����F�<-��@��B�-���Qrn���{��o[F�\#0����<�����Oq�-}�b��Ѝ ++1bD\\�{キaÆ������͛7oܸ�9*Y� tҏ�b)))ad� ??���n�Z��۷`��Hd�3Oy�����L��������j��ƍ ++ ++�;w���i:::Щ� 衇���5J��2��ʮ_��NZ��S���6����?�#'��<�~�Zn:o��M��f'3������;w�����ǎ{�����B� ��p�֭�bN�Z�'N�HKKs:�w��MIIa�27~�x�y4M[��m۶�_�$5TP���Ɲ;w��s�Ξ={RRR���O�>�aÆ���'N����1���o���999���Ǐg���v�Z�@yy�رcUj��`��ރ,�ᑟ���St_+}y5�G�::��j�>���EEEo����n7������7�|3;;�9ē}B��ŋ���8't�����?�r��A�h��ݻ��;epp�5k�o߾w�k����祡\�ӒG��f͚������?�����9���p�ڵkĈ�=����������͛����|�I�p�ݷo�F��������&$$0�w�A�I苚S�\�e���_!?C���>�Ps������Ⱥ���V{����˗�t�s�Ρ����xO�?:��h4 ><))���0""�����pl�-Ϙ1c�-[�9�K��M�6���?/--�<y����XT^^^__?}���ׯ�N�C�����̙�4M8p�n�?��3;�n�[�Vfx������ �y�����>�l�24�K���Y�,� �@P�j�������W�>z֣�F�A����v��92~�xtB����cbb�?���������***��ܼ't�l����F3z�����@SSӸq��o�!Æ �}qo߾ ��N��0aBpp�<��9h6�������������f4.\���|���f���`� /^�|���j ���E+**�i����V�b�I��]/���1���J:����n'Ђ���CBB������._�<cƌ]�v}��W��;vtwwggg?��3n�{֬Y+V�������y�GV�Z����j�*��1�����MQEQ��P4MWVV���s������j�رc�Ӓkjj(����\�t�c�=v���&��n��\����3g�0�'N��~����=z۶m�ߺukܸq4M�sZ7oތ^�T��41��U�`;�!�B�:���ЦNv2*j��� &TTT�;w�d2��G����t�={�dff���m�f0З[V�^]RRr�ڵ���3�������7n0g���f y��=$����R�՚�������\�sj�!�1�%�L&��r��Ō��^������RSSs�� tZr^^^VV���ܿ^^:�644�o��j7o�l2��F#sN�Q�~��_�|���>[�`��)S|�5V��ς�U�_ڑ��(�����˚m��́d3izzz���N�>{��C=�N�>r�:$B7:ZEX�nwrr�ƍ��(�:v��{�p:��N����6lXLL����=��%B&�����g���dJKK/\���sϝ:u�`0������4773�.'L�P\\|�ȑ+V����V�ŋ������/]��|l���833�����hm�� � ���aP�WSey�[۷o:o��*2������p�B�@��� ++G4*((8}�4:�;55����ӧ�9s��Gmooonn�1cƙ3g������O�<i������?�3�������t�c�i����/m6��EQ�g�{��kט/C@�����eff:t�o����}�����7o�\[[�EEEEEE���)))�W��[�n!���鎎�5GEE-^�/�lM�w�h���0����D�]�e��2N2��߂~pZ��}��E�ɄN�.,,��/���Ξ=�����ڵ�������K�.%''sN��я~�Y!�4�m۶|����:TVVVXX��>f̘���C��E����pp���C��&&&��?���f�j��lЋ/���1bĿ�˿P�|Ӈ)������')) ���O̝;�b���$�!$�ϴ���o����Iʅ��`7r�P#5O�_�k��ڵkÆ {�����{zz��˝NgQQ���*--u�����4My���^��555uuu���;w�\������Ą�������\.Wss�����qԃ�wﮬ�\�`ANN[������ֳg�1�P��D`@^���w�+7n��uE�YU�N��d�f�g6���IDAT䑶|�f�+;�ۧ�� � 2��\1PVV��mtBwii):�;>>����9�/Xzz��ɓ9ww��y����x����]���;v��������)���s��EDD��\���MH2¼��fNoo/����| ++6p Jw�Ut�T'C�9IEoq ��x�p�[�7�tC�,�Tg�Z=F�5�y ++i��&�$�ϧ�p ��E|[|dU�ʦ�w�p��״Sk����S��$u�<b)眏X�d���3�@-;�4��ֲGL92�� ++]|�)�u�Oi'�} |:�˼�矡J�h��5R�U�v�� ++u�8)��4�����@�.���!g�G!�(SH�sE��_�y��I^_�����X~�PX��`����-�Y�� Y����D��#����"L�4��$1O��cfɇN��] rz)wr�O] � �)�*?u��l�r�y���&���ʹȞ��N :Q��MhOY��l @R���`��p��xw/o��D*"�'/�����D[Q���$A�3�}�8�?�����o�b:_���me�V���S��o��X�7=}!��p���� ++Edp?$ ++U'S�y7^�#��S�.��I��.!^�y�C>Q*��c�t�賐���g6�ه�`��&^�H�-'��l���(J8PL>%� ++����()E�d^uu�ĉ�DK��z_T,��3�08F0�����-/��c�yw)� ++oϓh|��ЎT��F^��˘����g�<�B�R���$i;uE%���!��qܺu���m �t���"���p��7X4�A�b��� ����jA��z�d���%ޑGCQTVV:�}�[��a t�D o��N�.L�B͑��PG ++U�-�w3A���&G<�3��v���Ҽy��ՠ�����۷os��#(�b��- ++�Gxx�(Z�ޢz �/�(�%ķZ�-y�����oL�sc��(��?��_b/�������IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/zh_CN/index.md b/data/ukui-system-monitor/zh_CN/index.md +index 24cb54f..77a1c67 100644 +--- a/data/ukui-system-monitor/zh_CN/index.md ++++ b/data/ukui-system-monitor/zh_CN/index.md +@@ -38,7 +38,7 @@ +  + + ### 内存和交换空间历史 +-动态折线图统计系统运行内存和交换空间历史占用总量,右上方标签显示实时占用量和总量,点击查看内存情页。 ++动态折线图统计系统运行内存和交换空间历史占用总量,右上方标签显示实时占用量和总量,点击查看内存详情页。 + +  + +@@ -47,6 +47,11 @@ + +  + ++### 磁盘历史 ++动态折线图统计系统读取和写入磁盘速度历史数据,表格显示磁盘型号、容量、磁盘读取速度、磁盘写入速度和磁盘类型,点击侧边栏查看磁盘详情页。 ++ ++ ++ + <br> + + ## 文件系统 +diff --git a/src/controls/kchartview.cpp b/src/controls/kchartview.cpp +index 1e76b78..99e3d42 100644 +--- a/src/controls/kchartview.cpp ++++ b/src/controls/kchartview.cpp +@@ -144,11 +144,21 @@ void KChartView::drawAxisText(QPainter *painter) + int sectionSize = 6; + const QColor &textColor = palette.color(QPalette::Text); + painter->setPen(textColor); +- QRect titleRect(sectionSize + spacing, 0, painter->fontMetrics().width(m_axisLTitle), painter->fontMetrics().height()); +- painter->drawText(titleRect, Qt::AlignLeft | Qt::AlignVCenter, m_axisLTitle); +- painter->setPen(Qt::NoPen); +- painter->setBrush(m_RadioColor); +- painter->drawEllipse(0, titleRect.y() + qCeil((titleRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ QString language = QLocale::system().name(); ++ // 维吾尔 哈萨克斯 柯尔克孜 语言控件翻转 ++ if (language == "ug_CN" || language == "kk_KZ" || language == "ky_KG") { ++ QRect titleRect(0, 0, this->width() - sectionSize - spacing, painter->fontMetrics().height()); ++ painter->drawText(titleRect, Qt::AlignLeft | Qt::AlignVCenter, m_axisLTitle); ++ painter->setPen(Qt::NoPen); ++ painter->setBrush(m_RadioColor); ++ painter->drawEllipse(this->width() - sectionSize, titleRect.y() + qCeil((titleRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ } else { ++ QRect titleRect(sectionSize + spacing, 0, painter->fontMetrics().width(m_axisLTitle), painter->fontMetrics().height()); ++ painter->drawText(titleRect, Qt::AlignLeft | Qt::AlignVCenter, m_axisLTitle); ++ painter->setPen(Qt::NoPen); ++ painter->setBrush(m_RadioColor); ++ painter->drawEllipse(0, titleRect.y() + qCeil((titleRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ } + } + } + +diff --git a/src/controls/kchartview.h b/src/controls/kchartview.h +index 73e3f6c..7243dde 100644 +--- a/src/controls/kchartview.h ++++ b/src/controls/kchartview.h +@@ -34,8 +34,6 @@ public: + public slots: + void onUpdateData(qreal fData, int nItemIndex = 0); + +-signals: +- + protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; +diff --git a/src/img/read.svg b/src/img/read.svg +new file mode 100644 +index 0000000..cf600c9 +--- /dev/null ++++ b/src/img/read.svg +@@ -0,0 +1 @@ ++<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="14" height="14" viewBox="0 0 14 14"><g><g><ellipse cx="7" cy="7" rx="7" ry="7" fill="#3790FA" fill-opacity="1"/></g><g><path d="M6,3.5L9,3.5Q9.62132,3.5,10.06066,3.9393398Q10.5,4.37868,10.5,5L10.5,9Q10.5,9.62132,10.06066,10.06066Q9.62132,10.5,9,10.5L6,10.5Q5.9507543,10.5,5.9024549,10.49039Q5.854155,10.48078,5.808658,10.46194Q5.763161,10.44309,5.722215,10.41573Q5.681269,10.38837,5.646447,10.35355Q5.611625,10.31873,5.584265,10.27778Q5.556906,10.23684,5.53806,10.19134Q5.519215,10.14584,5.509607,10.09755Q5.5,10.04925,5.5,10Q5.5,9.95075,5.509607,9.90245Q5.519215,9.85415,5.53806,9.80866Q5.556906,9.76316,5.584265,9.72221Q5.611625,9.68127,5.646447,9.64645Q5.681269,9.61162,5.722215,9.58426Q5.763161,9.55691,5.808658,9.53806Q5.854155,9.519210000000001,5.9024549,9.50961Q5.9507543,9.5,6,9.5L9,9.5Q9.20711,9.5,9.35355,9.35355Q9.5,9.20711,9.5,9L9.5,5Q9.5,4.792893,9.35355,4.646447Q9.20711,4.5,9,4.5L6,4.5Q5.9507543,4.5,5.9024549,4.490393Q5.854155,4.480785,5.808658,4.46194Q5.763161,4.443094,5.722215,4.415735Q5.681269,4.388375,5.646447,4.353553Q5.611625,4.318731,5.584265,4.277785Q5.556906,4.236839,5.53806,4.191342Q5.519215,4.145845,5.509607,4.0975451Q5.5,4.0492457,5.5,4Q5.5,3.9507543,5.509607,3.9024549Q5.519215,3.854155,5.53806,3.808658Q5.556906,3.763161,5.584265,3.722215Q5.611625,3.681269,5.646447,3.646447Q5.681269,3.611625,5.722215,3.584265Q5.763161,3.556906,5.808658,3.5380599999999998Q5.854155,3.519215,5.9024549,3.509607Q5.9507543,3.5,6,3.5Z" fill-rule="evenodd" fill="#FFFFFF" fill-opacity="1"/></g><g transform="matrix(0,-0.9999999403953552,-0.9999999403953552,0,16.86770006418226,16.867700083988893)"><path d="M9.8447001953125,8.600000381469727C10.1209201953125,8.600000381469727,10.3447801953125,8.823863381469726,10.3447801953125,9.100009381469727L10.344720195312501,12.217650381469726L10.6608201953125,11.901550381469727C10.8560801953125,11.706290381469726,11.172660195312499,11.706290381469726,11.3679301953125,11.901550381469727C11.563190195312501,12.096810381469727,11.563190195312501,12.413400381469726,11.3679301953125,12.608660381469726L10.2552901953125,13.721290381469727C10.1532401953125,13.823340381469727,10.0180601953125,13.872060381469726,9.8843701953125,13.867440381469727C9.7515201953125,13.871360381469726,9.6173901953125,13.822620381469726,9.5159901953125,13.721210381469726L8.4141771953125,12.619400381469728C8.2189151953125,12.424140381469726,8.2189151953125,12.107560381469726,8.4141771953125,11.912290381469727C8.6094391953125,11.717030381469726,8.9260221953125,11.717030381469726,9.1212841953125,11.912290381469727L9.3447001953125,12.135710381469726L9.3447001953125,9.100000381469727C9.3447001953125,8.823858381469726,9.5685501953125,8.600000381469727,9.8447001953125,8.600000381469727Z" fill-rule="evenodd" fill="#FFFFFF" fill-opacity="1"/></g></g></svg> +\ No newline at end of file +diff --git a/src/img/write.svg b/src/img/write.svg +new file mode 100644 +index 0000000..d3b9e56 +--- /dev/null ++++ b/src/img/write.svg +@@ -0,0 +1 @@ ++<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="14" height="14" viewBox="0 0 14 14"><g><g><ellipse cx="7" cy="7" rx="7" ry="7" fill="#F1852B" fill-opacity="1"/></g><g><path d="M6,3.5L9,3.5Q9.62132,3.5,10.06066,3.9393398Q10.5,4.37868,10.5,5L10.5,9Q10.5,9.62132,10.06066,10.06066Q9.62132,10.5,9,10.5L6,10.5Q5.9507543,10.5,5.9024549,10.49039Q5.854155,10.48078,5.808658,10.46194Q5.763161,10.44309,5.722215,10.41573Q5.681269,10.38837,5.646447,10.35355Q5.611625,10.31873,5.584265,10.27778Q5.556906,10.23684,5.53806,10.19134Q5.519215,10.14584,5.509607,10.09755Q5.5,10.04925,5.5,10Q5.5,9.95075,5.509607,9.90245Q5.519215,9.85415,5.53806,9.80866Q5.556906,9.76316,5.584265,9.72221Q5.611625,9.68127,5.646447,9.64645Q5.681269,9.61162,5.722215,9.58426Q5.763161,9.55691,5.808658,9.53806Q5.854155,9.519210000000001,5.9024549,9.50961Q5.9507543,9.5,6,9.5L9,9.5Q9.20711,9.5,9.35355,9.35355Q9.5,9.20711,9.5,9L9.5,5Q9.5,4.792893,9.35355,4.646447Q9.20711,4.5,9,4.5L6,4.5Q5.9507543,4.5,5.9024549,4.490393Q5.854155,4.480785,5.808658,4.46194Q5.763161,4.443094,5.722215,4.415735Q5.681269,4.388375,5.646447,4.353553Q5.611625,4.318731,5.584265,4.277785Q5.556906,4.236839,5.53806,4.191342Q5.519215,4.145845,5.509607,4.0975451Q5.5,4.0492457,5.5,4Q5.5,3.9507543,5.509607,3.9024549Q5.519215,3.854155,5.53806,3.808658Q5.556906,3.763161,5.584265,3.722215Q5.611625,3.681269,5.646447,3.646447Q5.681269,3.611625,5.722215,3.584265Q5.763161,3.556906,5.808658,3.5380599999999998Q5.854155,3.519215,5.9024549,3.509607Q5.9507543,3.5,6,3.5Z" fill-rule="evenodd" fill="#FFFFFF" fill-opacity="1"/></g><g transform="matrix(0,-0.9999999403953552,0.9999999403953552,0,-5.600060904026009,11.59993916750318)"><path d="M4.57690896484375,8.600000381469727C4.85312896484375,8.600000381469727,5.07698896484375,8.823863381469726,5.07698896484375,9.100009381469727L5.07692896484375,12.217650381469726L5.39302896484375,11.901550381469727C5.58828896484375,11.706290381469726,5.90486896484375,11.706290381469726,6.10013896484375,11.901550381469727C6.29539896484375,12.096810381469727,6.29539896484375,12.413400381469726,6.10013896484375,12.608660381469726L4.98749896484375,13.721290381469727C4.88544896484375,13.823340381469727,4.75026896484375,13.872060381469726,4.61657896484375,13.867440381469727C4.48371896484375,13.871360381469726,4.34959896484375,13.822620381469726,4.24819896484375,13.721210381469726L3.14638596484375,12.619400381469728C2.95112346484375,12.424140381469726,2.95112346484375,12.107560381469726,3.14638596484375,11.912290381469727C3.34164796484375,11.717030381469726,3.65822996484375,11.717030381469726,3.85349196484375,11.912290381469727L4.07690896484375,12.135710381469726L4.07690896484375,9.100000381469727C4.07690896484375,8.823858381469726,4.30075896484375,8.600000381469727,4.57690896484375,8.600000381469727Z" fill-rule="evenodd" fill="#FFFFFF" fill-opacity="1"/></g></g></svg> +\ No newline at end of file +diff --git a/src/kleftwidget.cpp b/src/kleftwidget.cpp +index 564d52c..02b3bc9 100644 +--- a/src/kleftwidget.cpp ++++ b/src/kleftwidget.cpp +@@ -253,6 +253,10 @@ void KLeftWidget::initUI() + m_netHisWidget->setFixedSize(LEFT_BUTTON_WIDTH,168); + m_resLayout->addWidget(m_netHisWidget); + ++ m_pDiskHisWidget = new DiskHistoryWidget(); ++ m_pDiskHisWidget->setFixedSize(LEFT_BUTTON_WIDTH, 119); ++ m_resLayout->addWidget(m_pDiskHisWidget); ++ + m_mainLayout->addWidget(m_scrollOptions); + this->setLayout(m_mainLayout); + initThemeMode(); +@@ -273,11 +277,17 @@ void KLeftWidget::initConnections() + connect(m_netHisWidget, &NetHistoryWidget::clicked, this, [=](){ + Q_EMIT switchPage(m_buttonBar->model()->rowCount()+2); + }); ++ ++ connect(m_pDiskHisWidget, &DiskHistoryWidget::clicked, this, [=](){ ++ Q_EMIT switchPage(m_buttonBar->model()->rowCount()+3); ++ }); ++ + connect(m_updateStatusTimer, SIGNAL(timeout()), this, SLOT(onResourceUpdate())); + connect(this, &KLeftWidget::updateCpuStatus, m_cpuHisWidget, &CpuHistoryWidget::onUpdateData); + connect(this, &KLeftWidget::updateMemStatus, m_memHisWidget, &MemHistoryWidget::onUpdateMemData); + connect(this, &KLeftWidget::updateSwapStatus, m_memHisWidget, &MemHistoryWidget::onUpdateSwapData); + connect(this, &KLeftWidget::onUpdateNetStatus, m_netHisWidget, &NetHistoryWidget::onUpdateData); ++ connect(this, &KLeftWidget::onUpdateDiskStatus, m_pDiskHisWidget, &DiskHistoryWidget::onUpdateDiskData); + m_updateStatusTimer->start(2000); + } + +@@ -348,6 +358,7 @@ void KLeftWidget::onResourceUpdate() + //net work data get signal + getNetworkBytesData(m_totalRecvBytes, m_totalSentBytes, m_rateRecvBytes, m_rateSentBytes); + emit onUpdateNetStatus(m_totalSentBytes, m_rateSentBytes, m_totalRecvBytes, m_rateRecvBytes); ++ emit onUpdateDiskStatus(); + } + + bool KLeftWidget::getSwaponData(unsigned long long &swapSize, unsigned long long &swapUsed) +diff --git a/src/kleftwidget.h b/src/kleftwidget.h +index 8ac22a3..8e5114f 100644 +--- a/src/kleftwidget.h ++++ b/src/kleftwidget.h +@@ -36,6 +36,7 @@ + #include "sysresource/cpuhistorywidget.h" + #include "sysresource/memhistorywidget.h" + #include "sysresource/nethistorywidget.h" ++#include "sysresource/diskhistorywidget.h" + + #include "knavigationbar.h" + using namespace kdk; +@@ -62,6 +63,7 @@ signals: + void updateMemStatus(qreal memUsed, qreal memTotal); + void updateSwapStatus(qreal swapUsed, qreal swapTotal); + void onUpdateNetStatus(qreal sendTotalBytes, qreal sendRate, qreal recvTotalBytes, qreal recvRate); ++ void onUpdateDiskStatus(); + + private: + void paintEvent(QPaintEvent *e); +@@ -81,6 +83,7 @@ private: + CpuHistoryWidget *m_cpuHisWidget = nullptr; + MemHistoryWidget *m_memHisWidget = nullptr; + NetHistoryWidget *m_netHisWidget = nullptr; ++ DiskHistoryWidget *m_pDiskHisWidget = nullptr; + + QVBoxLayout *m_mainLayout = nullptr; + QHBoxLayout *m_titleLayout = nullptr; +diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp +index 024ef93..1bc1750 100644 +--- a/src/mainwindow.cpp ++++ b/src/mainwindow.cpp +@@ -142,9 +142,12 @@ void MainWindow::initConnections() + connect(m_leftWidget, &KLeftWidget::updateMemStatus, mMemDetailsWidget, &MemDetailsWidget::onUpdateMemData); + connect(m_leftWidget, &KLeftWidget::updateSwapStatus, mMemDetailsWidget, &MemDetailsWidget::onUpdateSwapData); + connect(m_leftWidget, &KLeftWidget::onUpdateNetStatus,mNetDetailsWidget,&NetDetailsWidget::onUpdateData); ++ connect(m_leftWidget, &KLeftWidget::onUpdateDiskStatus, m_pDiskDetailsWidget, &DiskDetailsWidget::onUpdateData); ++ + connect(mCpuDetailsWidget, &BaseDetailViewWidget::hideDetails, this, &MainWindow::onSwitchPage); + connect(mMemDetailsWidget, &BaseDetailViewWidget::hideDetails, this, &MainWindow::onSwitchPage); + connect(mNetDetailsWidget, &BaseDetailViewWidget::hideDetails, this, &MainWindow::onSwitchPage); ++ connect(m_pDiskDetailsWidget, &BaseDetailViewWidget::hideDetails, this, &MainWindow::onSwitchPage); + } + + void MainWindow::initOpacityGSettings() +@@ -210,6 +213,9 @@ void MainWindow::initRightPanel() + mNetDetailsWidget = new NetDetailsWidget(); + m_rightWidget->addPanel(mNetDetailsWidget, tr("Net Details"), "", panelIndex++); + ++ m_pDiskDetailsWidget = new DiskDetailsWidget(); ++ m_rightWidget->addPanel(m_pDiskDetailsWidget, tr("Disk Details"), "", panelIndex++); ++ + m_mainLayout->addWidget(m_rightWidget, 1); + } + +diff --git a/src/mainwindow.h b/src/mainwindow.h +index a9ad20a..7bc2a2a 100644 +--- a/src/mainwindow.h ++++ b/src/mainwindow.h +@@ -18,6 +18,7 @@ + #include "sysresource/cpudetailswidget.h" + #include "sysresource/memdetailswidget.h" + #include "sysresource/netdetailswidget.h" ++#include "sysresource/diskdetailswidget.h" + #include "sysresource/basedetailviewwidget.h" + + #include "trayicon.h" +@@ -93,6 +94,7 @@ private: + CpuDetailsWidget *mCpuDetailsWidget = nullptr; + MemDetailsWidget *mMemDetailsWidget = nullptr; + NetDetailsWidget *mNetDetailsWidget = nullptr; ++ DiskDetailsWidget *m_pDiskDetailsWidget = nullptr; + + QList<WindowId> m_listWinIds; + int mFirstKey = 0; +diff --git a/src/res.qrc b/src/res.qrc +index dcd7307..643c89f 100644 +--- a/src/res.qrc ++++ b/src/res.qrc +@@ -20,5 +20,7 @@ + <file>img/service_list.svg</file> + <file>img/nosearchresult_white.png</file> + <file>img/nosearchresult_black.png</file> ++ <file>img/write.svg</file> ++ <file>img/read.svg</file> + </qresource> + </RCC> +diff --git a/src/src.pro b/src/src.pro +index cd08185..b2a3502 100644 +--- a/src/src.pro ++++ b/src/src.pro +@@ -36,7 +36,8 @@ PKGCONFIG += kysdk-waylandhelper \ + kysdk-proc \ + kysdk-hardware \ + kysdk-net \ +- kysdk-realtime ++ kysdk-realtime \ ++ kysdk-disk + + # Automating generation .qm files from .ts files + CONFIG(release, debug|release) { +@@ -107,6 +108,11 @@ HEADERS += \ + sysresource/cpudetailswidget.h \ + sysresource/cpuhistorywidget.h \ + sysresource/detaillisttable.h \ ++ sysresource/diskdetailsmodel.h \ ++ sysresource/diskdetailswidget.h \ ++ sysresource/diskhistorywidget.h \ ++ sysresource/diskviewscrollarea.h \ ++ sysresource/diskitemwidget.h \ + sysresource/lightlabel.h \ + sysresource/memdetailsmodel.h \ + sysresource/memdetailswidget.h \ +@@ -115,6 +121,7 @@ HEADERS += \ + sysresource/netdetailswidget.h \ + sysresource/nethistorywidget.h \ + sysresource/netviewscrollarea.h \ ++ sysresource/netitemwidget.h \ + trayicon.h \ + xatom-helper.h \ + util.h \ +@@ -179,6 +186,11 @@ SOURCES += \ + sysresource/cpudetailswidget.cpp \ + sysresource/cpuhistorywidget.cpp \ + sysresource/detaillisttable.cpp \ ++ sysresource/diskdetailsmodel.cpp \ ++ sysresource/diskdetailswidget.cpp \ ++ sysresource/diskhistorywidget.cpp \ ++ sysresource/diskviewscrollarea.cpp \ ++ sysresource/diskitemwidget.cpp \ + sysresource/lightlabel.cpp \ + sysresource/memdetailsmodel.cpp \ + sysresource/memdetailswidget.cpp \ +@@ -187,6 +199,7 @@ SOURCES += \ + sysresource/netdetailswidget.cpp \ + sysresource/nethistorywidget.cpp \ + sysresource/netviewscrollarea.cpp \ ++ sysresource/netitemwidget.cpp \ + trayicon.cpp \ + xatom-helper.cpp \ + main.cpp \ +diff --git a/src/sysresource/chartviewwidget.cpp b/src/sysresource/chartviewwidget.cpp +index a40f38d..6c40f32 100644 +--- a/src/sysresource/chartviewwidget.cpp ++++ b/src/sysresource/chartviewwidget.cpp +@@ -1,6 +1,7 @@ + #include "chartviewwidget.h" + #include <QLabel> + #include <QHBoxLayout> ++#include <QApplication> + + const int margin = 6; + const int spacing = 6; +@@ -8,8 +9,8 @@ const int sectionSize = 6; + const int TextSpacing = 12; + const int allDatecount = 30; + +-ChartViewWidget::ChartViewWidget(QString name, QWidget *parent) +- : m_ifname(name), ++ChartViewWidget::ChartViewWidget(ChartViewTypes types, QWidget *parent) ++ : m_viewType(types), + QWidget(parent) + { + QFont ft1; +@@ -19,14 +20,6 @@ ChartViewWidget::ChartViewWidget(QString name, QWidget *parent) + + netChartView = new KChartView(this); + netChartView->setAxisTitle("0.0 b/s"); +- KChartAttr attr; +- attr.colorForeground = m_recvColor; +- attr.colorAlpha = 154; +- KChartAttr attr1; +- attr1.colorForeground = m_sentColor; +- attr1.colorAlpha = 154; +- netChartView->addItemAttr(attr); +- netChartView->addItemAttr(attr1); + + this->updateWidgetGeometry(); + +@@ -42,7 +35,25 @@ QString ChartViewWidget::getNCName() + return m_ifname; + } + +-void ChartViewWidget::updateDate(qreal sendRate, qreal recvRate) ++void ChartViewWidget::setData1Color(const QColor &color) ++{ ++ m_data1Color = color; ++ KChartAttr attr1; ++ attr1.colorForeground = m_data1Color; ++ attr1.colorAlpha = 154; ++ netChartView->addItemAttr(attr1); ++} ++ ++void ChartViewWidget::setData2Color(const QColor &color) ++{ ++ m_data2Color = color; ++ KChartAttr attr2; ++ attr2.colorForeground = m_data2Color; ++ attr2.colorAlpha = 154; ++ netChartView->addItemAttr(attr2); ++} ++ ++void ChartViewWidget::updateChartDate(qreal sendRate, qreal recvRate) + { + // 获取32次接收与发送速率中的最大值 + m_listData1 << sendRate; +@@ -65,18 +76,15 @@ void ChartViewWidget::updateDate(qreal sendRate, qreal recvRate) + m_maxData = qMax(m_maxData1, m_maxData2); + } + +- netChartView->updateAxisRTitle(commom::format::Format_Memory(m_maxData, KDK_KILOBYTE) + "/s"); ++ netChartView->updateAxisRTitle(commom::format::formatNetworkBrandWidth(m_maxData, false)); + +- m_recv_bps = commom::format::Format_Memory(recvRate, KDK_KILOBYTE) + "/s"; +- m_sent_bps = commom::format::Format_Memory(sendRate, KDK_KILOBYTE) + "/s"; ++ qreal newSendMaxData = netChartView->getRealMaxData(sendRate, 1); ++ qreal newRecvMaxData = netChartView->getRealMaxData(recvRate, 0); ++ qreal newMaxData = commom::format::chkNewMaxData(newSendMaxData>newRecvMaxData?newSendMaxData:newRecvMaxData); ++ netChartView->setMaxData(newMaxData); + +- double resultSend = 0; +- double resultRecv = 0; +- kdkVolumeBaseNumericalConvert(sendRate, KDK_KILOBYTE, KDK_MEGABYTE, &resultSend); +- kdkVolumeBaseNumericalConvert(recvRate, KDK_KILOBYTE, KDK_MEGABYTE, &resultRecv); +- +- netChartView->onUpdateData(resultSend, 1); +- netChartView->onUpdateData(resultRecv, 0); ++ netChartView->onUpdateData(sendRate, 1); ++ netChartView->onUpdateData(recvRate, 0); + + this->update(); + } +@@ -110,46 +118,6 @@ void ChartViewWidget::paintEvent(QPaintEvent *event) + painter.drawText(ifnameRect, Qt::AlignLeft | Qt::AlignVCenter, m_ifname); + + painter.setPen(textColor); +- if (m_mode == TITLE_HORIZONTAL) { +- QString strLeftBrackets = "("; +- QRect leftBracketsRect(ifnameRect.right() + spacing, ifnameRect.y(), painter.fontMetrics().width(strLeftBrackets), painter.fontMetrics().height()); +- painter.drawText(leftBracketsRect, Qt::AlignLeft | Qt::AlignVCenter, strLeftBrackets); +- +- QString strRecvData = tr("Receive"); +- strRecvData = strRecvData + " " + m_recv_bps; +- QRect recvRect(leftBracketsRect.right() + spacing * 2 + sectionSize, ifnameRect.y(), painter.fontMetrics().width(strRecvData), painter.fontMetrics().height()); +- painter.drawText(recvRect, Qt::AlignLeft | Qt::AlignVCenter, strRecvData); +- +- QString strSentData = tr("Send"); +- strSentData = strSentData + " " + m_sent_bps + " )"; +- QRect sentRect(sectionSize + recvRect.right() + 3 * spacing, ifnameRect.y(), painter.fontMetrics().width(strSentData), painter.fontMetrics().height()); +- painter.drawText(sentRect, Qt::AlignLeft | Qt::AlignVCenter, strSentData); +- +- painter.setPen(Qt::NoPen); +- painter.setBrush(m_recvColor); +- painter.drawEllipse(leftBracketsRect.right() + spacing, leftBracketsRect.y() + qCeil((leftBracketsRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); +- +- painter.setBrush(m_sentColor); +- painter.drawEllipse(recvRect.right() + 2 * spacing, recvRect.y() + qCeil((recvRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); +- } else { +- +- QString strRecvData = tr("Receive"); +- strRecvData = strRecvData + " " + m_recv_bps; +- QRect recvRect(margin + spacing + sectionSize, ifnameRect.bottom(), painter.fontMetrics().width(strRecvData), painter.fontMetrics().height()); +- painter.drawText(recvRect, Qt::AlignLeft | Qt::AlignVCenter, strRecvData); +- +- QString strSentData = tr("Send"); +- strSentData = strSentData + " " + m_sent_bps; +- QRect sentRect(margin + spacing + sectionSize, recvRect.bottom(), painter.fontMetrics().width(strSentData), painter.fontMetrics().height()); +- painter.drawText(sentRect, Qt::AlignLeft | Qt::AlignVCenter, strSentData); +- +- painter.setPen(Qt::NoPen); +- painter.setBrush(m_recvColor); +- painter.drawEllipse(margin, recvRect.y() + qCeil((recvRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); +- +- painter.setBrush(m_sentColor); +- painter.drawEllipse(margin, sentRect.y() + qCeil((sentRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); +- } + + } + +@@ -162,7 +130,6 @@ void ChartViewWidget::resizeEvent(QResizeEvent *event) + void ChartViewWidget::mousePressEvent(QMouseEvent *event) + { + QWidget::mousePressEvent(event); +- m_isActive = true; + emit clicked(m_ifname); + update(); + } +@@ -190,3 +157,10 @@ void ChartViewWidget::updateWidgetGeometry() + } + netChartView->update(); + } ++ ++void ChartViewWidget::setAxisTitle(const QString &text) ++{ ++ m_axisTitle = text; ++ update(); ++} ++ +diff --git a/src/sysresource/chartviewwidget.h b/src/sysresource/chartviewwidget.h +index 679af1d..d348939 100644 +--- a/src/sysresource/chartviewwidget.h ++++ b/src/sysresource/chartviewwidget.h +@@ -13,17 +13,29 @@ class ChartViewWidget : public QWidget + { + Q_OBJECT + public: ++ enum ChartViewTypes { ++ MEM_CHART, //内存 ++ NET_CHART, //网络 ++ BLOCK_CHART //磁盘 ++ }; + enum TitleStyle { + TITLE_HORIZONTAL = 0,// 单个模式 + TITLE_VERTICAL = 1 // 多个模式 + }; +- explicit ChartViewWidget(QString name, QWidget *parent = nullptr); ++ explicit ChartViewWidget(ChartViewWidget::ChartViewTypes types, QWidget *parent = nullptr); + ~ChartViewWidget(); + + void setMode(int mode); + void setActive(bool active); + QString getNCName(); + ++ ++ void setAxisTitle(const QString &text); ++ ++ void setData1Color(const QColor &color); ++ ++ void setData2Color(const QColor &color); ++ + private: + int m_mode = TITLE_HORIZONTAL; + bool m_isActive = false; +@@ -31,8 +43,9 @@ private: + QString m_ifname; // 网卡名称 + QString m_recv_bps; // 接受速率 + QString m_sent_bps; // 发送速率 +- QColor m_recvColor {"#B37FEB"}; +- QColor m_sentColor {"#FF7875"}; ++ QColor m_data1Color = {"#B37FEB"}; ++ QColor m_data2Color = {"#FF7875"}; ++ QString m_axisTitle = {"100%"}; + KChartView *netChartView = nullptr; + + QList<qreal> m_listData1; +@@ -41,7 +54,11 @@ private: + qreal m_maxData2 = 1; + qreal m_maxData; + ++ ChartViewTypes m_viewType = ChartViewTypes::MEM_CHART; ++ ++private: + void updateWidgetGeometry(); ++ void drawBackPixmap(); + + protected: + void paintEvent(QPaintEvent *event); +@@ -52,8 +69,7 @@ signals: + void clicked(const QString &mac); + + public slots: +- void updateDate(qreal sendRate, qreal recvRate); +- ++ void updateChartDate(qreal sendRate, qreal recvRate); + }; + + #endif // CHARTVIEWWIDGET_H +diff --git a/src/sysresource/commoninfo.cpp b/src/sysresource/commoninfo.cpp +index a5d8a7a..98eed5d 100644 +--- a/src/sysresource/commoninfo.cpp ++++ b/src/sysresource/commoninfo.cpp +@@ -394,7 +394,6 @@ QList<INet6Addr> netInfo::getIPv6AddressList(const char *strKey) + + namespace commom { + +- + const QString format::Format_Memory(long data, KDKVolumeBaseType baseType) + { + char resultData[50] = {0}; +@@ -402,8 +401,220 @@ const QString format::Format_Memory(long data, KDKVolumeBaseType baseType) + const char* b = (std::to_string(data)+ UnitSuffixMem[baseType]).c_str(); + kdkVolumeBaseCharacterConvert(b, KDK_GIGABYTE, resultData); + +- return data == 0 ? "-" : QString::fromUtf8(resultData); ++ return data == 0 ? "0KB" : QString::fromUtf8(resultData); ++} ++ ++const QString format::formatNetworkBrandWidth(guint64 size, bool isTotal) ++{ ++ enum { ++ K_INDEX, ++ M_INDEX, ++ G_INDEX, ++ T_INDEX ++ }; ++ char data[128] = {0}; ++ sprintf(data,"%lu",size); ++ char result_data[128] = {0}; ++ double m_speed = 0; ++ KDKVolumeBaseType m_KDKVolumeBaseType; ++ ++ QList<guint64> factorList; ++ factorList.append(G_GUINT64_CONSTANT(1) << 10);//KiB ++ factorList.append(G_GUINT64_CONSTANT(1) << 20);//MiB ++ factorList.append(G_GUINT64_CONSTANT(1) << 30);//GiB ++ factorList.append(G_GUINT64_CONSTANT(1) << 40);//TiB ++ ++ guint64 factor; ++ QString format; ++ if (size < factorList.at(M_INDEX)) { ++ m_KDKVolumeBaseType = KDK_KILOBYTE; ++ factor = factorList.at(K_INDEX); ++ if (isTotal) { ++ format = QObject::tr("KiB"); ++ } else { ++ format = QObject::tr("KiB/s"); ++ } ++ } else if (size < factorList.at(G_INDEX)) { ++ m_KDKVolumeBaseType = KDK_MEGABYTE; ++ factor = factorList.at(M_INDEX); ++ if (isTotal) { ++ format = QObject::tr("MiB"); ++ } else { ++ format = QObject::tr("MiB/s"); ++ } ++ } else if (size < factorList.at(T_INDEX)) { ++ m_KDKVolumeBaseType = KDK_GIGABYTE; ++ factor = factorList.at(G_INDEX); ++ if (isTotal) { ++ format = QObject::tr("GiB"); ++ } else { ++ format = QObject::tr("GiB/s"); ++ } ++ } else { ++ m_KDKVolumeBaseType = KDK_TERABYTE; ++ factor = factorList.at(T_INDEX); ++ if (isTotal) { ++ format = QObject::tr("TiB"); ++ } else { ++ format = QObject::tr("TiB/s"); ++ } ++ } ++ ++ if (size > 1024 && kdkVolumeBaseCharacterConvert(data, m_KDKVolumeBaseType, result_data) == KDK_NOERR) { ++ QString formatted_result = ""; ++ sscanf(result_data, "%lf", &m_speed); ++ formatted_result.setNum(m_speed, 'f', 1); ++ return formatted_result + format; ++ } else { ++ std::string formatted_result(make_string(g_strdup_printf("%.1f", size / (double)factor))); ++ return QString::fromStdString(formatted_result) + format; ++ } ++} ++ ++const qreal format::chkNewMaxData(qreal qNewMaxData) ++{ ++ qreal newMaxData = 0; ++ if (qNewMaxData < 20 * 1024) { ++ newMaxData = 20 * 1024; ++ } else if (qNewMaxData >= 20 *1024 && qNewMaxData < 100 * 1024) { ++ newMaxData = 100 * 1024; ++ } else if (qNewMaxData >= 100 *1024 && qNewMaxData < 500 * 1024) { ++ newMaxData = 500 * 1024; ++ } else if (qNewMaxData >= 500 *1024 && qNewMaxData < 1 * 1024 * 1024) { ++ newMaxData = 1 * 1024 * 1024; ++ } else if (qNewMaxData >= 1 * 1024 * 1024 && qNewMaxData < 2 * 1024 * 1024) { ++ newMaxData = 2 * 1024 * 1024; ++ } else if (qNewMaxData >= 2 * 1024 * 1024 && qNewMaxData < 4 * 1024 * 1024) { ++ newMaxData = 4 * 1024 * 1024; ++ } else if (qNewMaxData >= 4 * 1024 * 1024 && qNewMaxData < 8 * 1024 * 1024) { ++ newMaxData = 8 * 1024 * 1024; ++ } else if (qNewMaxData >= 8 * 1024 * 1024 && qNewMaxData < 16 * 1024 * 1024) { ++ newMaxData = 16 * 1024 * 1024; ++ } else if (qNewMaxData >= 16 * 1024 * 1024 && qNewMaxData < 32 * 1024 * 1024) { ++ newMaxData = 32 * 1024 * 1024; ++ } else if (qNewMaxData >= 32 * 1024 * 1024 && qNewMaxData < 64 * 1024 * 1024) { ++ newMaxData = 64 * 1024 * 1024; ++ } else if (qNewMaxData >= 64 * 1024 * 1024 && qNewMaxData < 128 * 1024 * 1024) { ++ newMaxData = 128 * 1024 * 1024; ++ } else if (qNewMaxData >= 128 * 1024 * 1024 && qNewMaxData < 256 * 1024 * 1024) { ++ newMaxData = 256 * 1024 * 1024; ++ } else if (qNewMaxData >= 256 * 1024 * 1024 && qNewMaxData < 512 * 1024 * 1024) { ++ newMaxData = 512 * 1024 * 1024; ++ } else if (qNewMaxData >= 512 * 1024 * 1024 && qNewMaxData < 1024 * 1024 * 1024) { ++ newMaxData = (quint64)1024 * 1024 * 1024; ++ } else { ++ newMaxData = (quint64)2 * 1024 * 1024 * 1024; ++ } ++ return newMaxData; ++} ++ ++} ++ ++ ++QString diskInfo::getDiskModel(const QString &strKey) ++{ ++ std::string str = strKey.toStdString(); ++ const char *diskName = str.c_str(); ++ ++ char *ret = kdk_get_hard_model(diskName); ++ QString model = QString::fromUtf8(ret); ++ free(ret); ++ return model; ++} ++ ++QString diskInfo::getDiskCapacity(const QString &strKey) ++{ ++ std::string str = strKey.toStdString(); ++ const char *diskName = str.c_str(); ++ ++ kdk_diskinfo *diskinfo = kdk_get_diskinfo(diskName); ++ float size = diskinfo->total_size_MiB; ++ kdk_free_diskinfo(diskinfo); ++ ++ return commom::format::Format_Memory(size, KDK_MEGABYTE); ++} ++ ++QString diskInfo::getDiskType(const QString &strKey) ++{ ++ std::string str = strKey.toStdString(); ++ const char *diskName = str.c_str(); ++ ++ char *ret = kdk_get_hard_type(diskName); ++ QString type = QString::fromUtf8(ret); ++ free(ret); ++ ++ return type; ++} ++ ++QStringList diskInfo::getDiskName() ++{ ++ char **_disklist = kdk_get_hard_disk(); ++ QStringList diskList; ++ int index = 0; ++ while (_disklist != nullptr && _disklist[index]) { ++ diskList.append(_disklist[index]); ++ index++; ++ } ++ kdk_free_disklist(_disklist); ++ ++ return diskList; + } + ++DiskSpeedInfo *DiskSpeedInfo::m_pDiskSpeedInfo = nullptr; ++DiskSpeedInfo *DiskSpeedInfo::instance() ++{ ++ if (m_pDiskSpeedInfo == nullptr) { ++ m_pDiskSpeedInfo = new DiskSpeedInfo; ++ } ++ return m_pDiskSpeedInfo; ++} ++ ++DiskSpeedInfo::DiskSpeedInfo(QObject *parent) : QObject(parent) ++{ ++ ++} ++ ++DiskSpeedInfo::~DiskSpeedInfo() ++{ ++ ++} ++ ++double DiskSpeedInfo::readSpeed(const QString &strKey) ++{ ++ return m_speedInfo[strKey].readSpeed; + } + ++double DiskSpeedInfo::writeSpeed(const QString &strKey) ++{ ++ return m_speedInfo[strKey].writeSpeed; ++} ++ ++QString DiskSpeedInfo::readSpeedStr(const QString &strKey) ++{ ++ return m_speedInfo[strKey].readSpeedStr; ++} ++ ++QString DiskSpeedInfo::writeSpeedStr(const QString &strKey) ++{ ++ return m_speedInfo[strKey].writeSpeedStr; ++} ++ ++void DiskSpeedInfo::updateDiskSpeed(const QString &strKey) ++{ ++ std::string str = strKey.toStdString(); ++ const char *diskName = str.c_str(); ++ ++ DiskSpeed tmpSpeed; ++ ++ tmpSpeed.readSpeed = kdk_get_disk_read_speed(diskName); ++ tmpSpeed.readSpeedStr = commom::format::Format_Memory(tmpSpeed.readSpeed, KDK_KILOBYTE) + "/s"; ++ ++ tmpSpeed.writeSpeed = kdk_get_disk_write_speed(diskName); ++ tmpSpeed.writeSpeedStr = commom::format::Format_Memory(tmpSpeed.writeSpeed, KDK_KILOBYTE) + "/s"; ++ ++ if (m_speedInfo.keys().contains(strKey)) { ++ m_speedInfo[strKey] = tmpSpeed; ++ } else { ++ m_speedInfo.insert(strKey, tmpSpeed); ++ } ++} +diff --git a/src/sysresource/commoninfo.h b/src/sysresource/commoninfo.h +index 409d7dc..0d22b1f 100644 +--- a/src/sysresource/commoninfo.h ++++ b/src/sysresource/commoninfo.h +@@ -5,10 +5,13 @@ + #include <QVariant> + #include <stdlib.h> + ++#include "../util.h" ++ + #include "kysdk/kysdk-base/kyutils.h" + #include <kysdk/kysdk-system/libkyrtinfo.h> + #include <kysdk/kysdk-system/libkycpu.h> + #include <kysdk/kysdk-system/libkysysinfo.h> ++#include <kysdk/kysdk-system/libkydiskinfo.h> + namespace cpuInfo { + + QString getUtilization(); // 获取总利用率 +@@ -97,6 +100,42 @@ QList<INet4Addr> getIPv4AddressList(const char *strKey); // 获取ipv4地址列 + QList<INet6Addr> getIPv6AddressList(const char *strKey); // 获取ipv6地址列表 + } + ++namespace diskInfo { ++ QString getDiskModel(const QString &strKey); // 获取磁盘型号 ++ QString getDiskCapacity(const QString &strKey); // 获取磁盘容量 ++ QString getDiskType(const QString &strKey); // 获取磁盘类型 ++ ++ QStringList getDiskName(); // 获取磁盘列表 ++} ++ ++typedef struct _DiskSpeed ++{ ++ double readSpeed; ++ double writeSpeed; ++ QString readSpeedStr; ++ QString writeSpeedStr; ++} DiskSpeed; ++ ++class DiskSpeedInfo : public QObject ++{ ++ Q_OBJECT ++public: ++ static DiskSpeedInfo *instance(); ++ ++ DiskSpeedInfo(QObject *parent = 0); ++ ~DiskSpeedInfo(); ++ ++ double readSpeed(const QString &strKey); ++ double writeSpeed(const QString &strKey); ++ QString readSpeedStr(const QString &strKey); ++ QString writeSpeedStr(const QString &strKey); ++ ++ void updateDiskSpeed(const QString &strKey); // 更新磁盘读写速度 ++private: ++ QMap<QString, DiskSpeed> m_speedInfo; ++ static DiskSpeedInfo *m_pDiskSpeedInfo; ++}; ++ + namespace commom { + + namespace format { +@@ -107,6 +146,10 @@ const char *const UnitSuffixMem[] = {"B","KB", "MB", "GB", "TB", "PB", "EB"}; + + const QString Format_Memory(long data, KDKVolumeBaseType baseType); + ++const QString formatNetworkBrandWidth(guint64 size, bool isTotal); ++ ++const qreal chkNewMaxData(qreal qNewMaxData); ++ + } + } + +diff --git a/src/sysresource/diskdetailsmodel.cpp b/src/sysresource/diskdetailsmodel.cpp +new file mode 100755 +index 0000000..4cc5b61 +--- /dev/null ++++ b/src/sysresource/diskdetailsmodel.cpp +@@ -0,0 +1,82 @@ ++#include "diskdetailsmodel.h" ++ ++DiskDetailsModel::DiskDetailsModel(QObject *parent) : QAbstractTableModel(parent) ++{ ++ ++} ++ ++DiskDetailsModel::~DiskDetailsModel() ++{ ++ ++} ++QVariant DiskDetailsModel::data(const QModelIndex &index, int role) const ++{ ++ if (!index.isValid()) ++ return QVariant(); ++ ++ int row = index.row(); ++ int column = index.column(); ++ ++ if (role == Qt::DisplayRole) { ++ switch (row) { ++ case 0: ++ if (column == 0) ++ return tr("Model"); //型号 ++ else if (column == 1) ++ return tr("Capacity"); //容量 ++ break; ++ case 1: ++ if (column == 0) ++ return tr("Read Speed"); //读取速度 ++ else if (column == 1) ++ return tr("Write Speed"); //写入速度 ++ break; ++ case 2: ++ if (column == 0) ++ return tr("Type"); //类型 ++ break; ++ default: ++ break; ++ } ++ } else if (role == Qt::UserRole) { ++ switch (row) { ++ case 0: ++ if (column == 0) ++ return m_showinfo.model; ++ else if (column == 1) ++ return m_showinfo.size; ++ break; ++ case 1: ++ if (column == 0) ++ return m_showinfo.readSpeed; ++ else if (column == 1) ++ return m_showinfo.writeSpeed; ++ break; ++ case 2: ++ if (column == 0) ++ return m_showinfo.type; ++ break; ++ default: ++ break; ++ } ++ } else if (role == Qt::TextColorRole) { ++ const auto &palette = QPalette(); ++ return palette.color(QPalette::Text); ++ } ++ ++ return QVariant(); ++} ++ ++void DiskDetailsModel::onModelUpdated() ++{ ++ QAbstractTableModel::dataChanged(index(0, 0), index(2, 1)); ++} ++ ++void DiskDetailsModel::refreshDiskInfo(const QString &strKey) ++{ ++ m_showinfo.model = diskInfo::getDiskModel(strKey); ++ m_showinfo.size = diskInfo::getDiskCapacity(strKey); ++ m_showinfo.readSpeed = DiskSpeedInfo::instance()->readSpeedStr(strKey); ++ m_showinfo.writeSpeed = DiskSpeedInfo::instance()->writeSpeedStr(strKey); ++ m_showinfo.type = diskInfo::getDiskType(strKey); ++} +diff --git a/src/sysresource/diskdetailsmodel.h b/src/sysresource/diskdetailsmodel.h +new file mode 100755 +index 0000000..5a781c5 +--- /dev/null ++++ b/src/sysresource/diskdetailsmodel.h +@@ -0,0 +1,59 @@ ++#ifndef DISKDETAILSMODEL_H ++#define DISKDETAILSMODEL_H ++ ++#include <QObject> ++#include <QAbstractTableModel> ++#include <QPalette> ++ ++#include "commoninfo.h" ++using namespace commom::format; ++ ++typedef struct _diskInfo ++{ ++ QString model; ++ QString size; ++ QString readSpeed; ++ QString writeSpeed; ++ QString type; ++ ++} diskShowInfo; ++ ++class DiskDetailsModel : public QAbstractTableModel ++{ ++ Q_OBJECT ++public: ++ DiskDetailsModel(QObject *parent = nullptr); ++ ~DiskDetailsModel(); ++ ++ /** ++ * @brief refreshDiskInfo 刷新磁盘信息 ++ * @param strKey 磁盘名称信息 ++ */ ++ void refreshDiskInfo(const QString &strKey); ++ ++private: ++ diskShowInfo m_showinfo; ++ ++protected: ++ int rowCount(const QModelIndex &) const ++ { ++ return 3; ++ } ++ ++ int columnCount(const QModelIndex &) const ++ { ++ return 2; ++ } ++ ++ QVariant data(const QModelIndex &index, int role) const; ++ ++ Qt::ItemFlags flags(const QModelIndex &) const ++ { ++ return Qt::NoItemFlags; ++ } ++ ++public slots: ++ void onModelUpdated(); ++}; ++ ++#endif // DISKDETAILSMODEL_H +diff --git a/src/sysresource/diskdetailswidget.cpp b/src/sysresource/diskdetailswidget.cpp +new file mode 100755 +index 0000000..695c096 +--- /dev/null ++++ b/src/sysresource/diskdetailswidget.cpp +@@ -0,0 +1,47 @@ ++#include "diskdetailswidget.h" ++ ++DiskDetailsWidget::DiskDetailsWidget(QWidget *parent): BaseDetailViewWidget(parent) ++{ ++ this->setAttribute(Qt::WA_TranslucentBackground); ++ initUI(); ++} ++ ++DiskDetailsWidget::~DiskDetailsWidget() ++{ ++ ++} ++ ++void DiskDetailsWidget::initUI() ++{ ++ setTitle(tr("Disk")); ++ ++ m_pDiskGraphScrollArea = new DiskViewScrollArea(); ++ ++ // 详情列表 ++ m_pDetailModel = new DiskDetailsModel(); ++ m_pDetailList = new DetailListTable(m_pDetailModel); ++ m_pDetailList->setFixedHeight(108); ++ mCurrentDiskName = m_pDiskGraphScrollArea->getCurrentDiskName(); ++ m_pDetailModel->refreshDiskInfo(mCurrentDiskName); ++ ++ QHBoxLayout *listHLayout = new QHBoxLayout(this); ++ listHLayout->addWidget(m_pDetailList); ++ ++ mMainLayout->addWidget(m_pDiskGraphScrollArea); ++ mMainLayout->addSpacing(8); ++ mMainLayout->addLayout(listHLayout); ++ ++ connect(m_pDiskGraphScrollArea, &DiskViewScrollArea::changeInfo, this, [=](const QString &diskName){ ++// m_pDetailModel->refreshDiskInfo(diskName); ++ mCurrentDiskName = diskName; ++ }); ++} ++ ++void DiskDetailsWidget::onUpdateData() ++{ ++ m_pDiskGraphScrollArea->onUpdateData(); ++ m_pDetailModel->refreshDiskInfo(mCurrentDiskName); ++ // 刷新数据列表 ++ m_pDetailModel->onModelUpdated(); ++} ++ +diff --git a/src/sysresource/diskdetailswidget.h b/src/sysresource/diskdetailswidget.h +new file mode 100755 +index 0000000..4623686 +--- /dev/null ++++ b/src/sysresource/diskdetailswidget.h +@@ -0,0 +1,37 @@ ++#ifndef DISKDETAILSWIDGET_H ++#define DISKDETAILSWIDGET_H ++ ++#include <QWidget> ++ ++#include "basedetailviewwidget.h" ++#include "detaillisttable.h" ++#include "diskdetailsmodel.h" ++#include "diskviewscrollarea.h" ++ ++class DiskDetailsWidget : public BaseDetailViewWidget ++{ ++ Q_OBJECT ++public: ++ explicit DiskDetailsWidget(QWidget *parent = nullptr); ++ ++ ~DiskDetailsWidget(); ++ ++private: ++ void initUI(); ++ ++private: ++ DiskViewScrollArea *m_pDiskGraphScrollArea = nullptr; ++ ++ DetailListTable *m_pDetailList = nullptr; ++ DiskDetailsModel *m_pDetailModel = nullptr; ++ ++ QString mCurrentDiskName; ++ ++public slots: ++ void onUpdateData(); ++ ++signals: ++ ++}; ++ ++#endif // DISKDETAILSWIDGET_H +diff --git a/src/sysresource/diskhistorywidget.cpp b/src/sysresource/diskhistorywidget.cpp +new file mode 100755 +index 0000000..0f4f220 +--- /dev/null ++++ b/src/sysresource/diskhistorywidget.cpp +@@ -0,0 +1,231 @@ ++#include "diskhistorywidget.h" ++#include <QPainter> ++#include <QPainterPath> ++#include <QIcon> ++#include <QLocale> ++#include "commoninfo.h" ++ ++#include "../macro.h" ++ ++DiskHistoryWidget::DiskHistoryWidget(QWidget *parent) ++ : QWidget(parent) ++{ ++ m_curFontSize = DEFAULT_FONT_SIZE; ++ setAttribute(Qt::WA_TranslucentBackground); ++ initUI(); ++ initStyleTheme(); ++} ++ ++DiskHistoryWidget::~DiskHistoryWidget() ++{ ++ if (m_pStyleSettings) { ++ delete m_pStyleSettings; ++ m_pStyleSettings = nullptr; ++ } ++} ++ ++void DiskHistoryWidget::initUI() ++{ ++ m_colorBg = QColor("#F5F5F5"); ++ ++ // 初始化布局 ++ m_pMainVLayout = new QVBoxLayout(); ++ m_pMainVLayout->setContentsMargins(12, 0, 12, 0); ++ m_pMainVLayout->setSpacing(0); ++ m_pReadHLayout = new QHBoxLayout(); ++ m_pReadHLayout->setContentsMargins(0, 0, 0, 0); ++ m_pReadHLayout->setSpacing(3); ++ m_pWriteHLayout = new QHBoxLayout(); ++ m_pWriteHLayout->setContentsMargins(0, 0, 0, 0); ++ m_pWriteHLayout->setSpacing(3); ++ ++ //初始化控件 ++ m_pDiskTitleLabel = new KLabel(); ++ m_pDiskTitleLabel->setText(tr("Disk reading and writing")); ++ m_pDiskTitleLabel->setFixedWidth(160); ++ m_pDiskTitleLabel->setAlignment(Qt::AlignLeft); ++ ++ m_pIconReadLabel = new QLabel(); ++ m_pIconReadLabel->setPixmap(QIcon::fromTheme(":/img/read.svg").pixmap(14,14)); ++ m_pReadHLayout->addWidget(m_pIconReadLabel, 0, Qt::AlignLeft|Qt::AlignVCenter); ++ m_pReadTitleLabel = new KLabel(); ++ m_pReadTitleLabel->setText(tr("Disk Read")); ++ m_pReadTitleLabel->setFixedWidth(60); ++ m_pReadTitleLabel->setAlignment(Qt::AlignLeft); ++ m_pReadHLayout->addWidget(m_pReadTitleLabel, 1, Qt::AlignLeft|Qt::AlignVCenter); ++ m_pReadValueLabel = new KLabel(); ++ m_pReadValueLabel->setText("0MB/s"); ++ m_pReadValueLabel->setFixedWidth(80); ++ ++ m_pIconWriteLabel = new QLabel(); ++ m_pIconWriteLabel->setPixmap(QIcon::fromTheme(":/img/write.svg").pixmap(14,14)); ++ m_pWriteHLayout->addWidget(m_pIconWriteLabel, 0, Qt::AlignLeft|Qt::AlignVCenter); ++ m_pWriteTitleLabel = new KLabel(); ++ m_pWriteTitleLabel->setText(tr("Disk Write")); ++ m_pWriteTitleLabel->setFixedWidth(60); ++ m_pWriteTitleLabel->setAlignment(Qt::AlignLeft); ++ m_pWriteHLayout->addWidget(m_pWriteTitleLabel, 1, Qt::AlignLeft|Qt::AlignVCenter); ++ m_pWriteValueLabel = new KLabel(); ++ m_pWriteValueLabel->setText("0MB/s"); ++ m_pWriteValueLabel->setFixedWidth(80); ++ ++ // 维吾尔 哈萨克斯 柯尔克孜 语言控件翻转 ++ QString language = QLocale::system().name(); ++ if (language == "ug_CN" || language == "kk_KZ" || language == "ky_KG") { ++ m_pReadValueLabel->setAlignment(Qt::AlignLeft); ++ m_pReadHLayout->addWidget(m_pReadValueLabel, 1, Qt::AlignLeft|Qt::AlignVCenter); ++ m_pWriteValueLabel->setAlignment(Qt::AlignLeft); ++ m_pWriteHLayout->addWidget(m_pWriteValueLabel, 1, Qt::AlignLeft|Qt::AlignVCenter); ++ } else { ++ m_pReadValueLabel->setAlignment(Qt::AlignRight); ++ m_pReadHLayout->addWidget(m_pReadValueLabel, 1, Qt::AlignRight|Qt::AlignVCenter); ++ m_pWriteValueLabel->setAlignment(Qt::AlignRight); ++ m_pWriteHLayout->addWidget(m_pWriteValueLabel, 1, Qt::AlignRight|Qt::AlignVCenter); ++ } ++ ++ m_pMainVLayout->addWidget(m_pDiskTitleLabel); ++ m_pMainVLayout->addSpacing(10); ++ m_pMainVLayout->addLayout(m_pReadHLayout); ++ m_pMainVLayout->addLayout(m_pWriteHLayout); ++ this->setLayout(m_pMainVLayout); ++ ++} ++ ++void DiskHistoryWidget::initStyleTheme() ++{ ++ const QByteArray idd(THEME_QT_SCHEMA); ++ if(QGSettings::isSchemaInstalled(idd)) { ++ m_pStyleSettings = new QGSettings(idd); ++ } ++ if (m_pStyleSettings) { ++ //监听主题改变 ++ connect(m_pStyleSettings, &QGSettings::changed, this, [=](const QString &key){ ++ themeChangedSlot(key); ++ }); ++ auto variant = m_pStyleSettings->get(FONT_SIZE); ++ if (variant.isValid()) { ++ m_curFontSize = m_pStyleSettings->get(FONT_SIZE).toString().toFloat(); ++ onThemeFontChange(m_curFontSize); ++ } ++ variant = m_pStyleSettings->get("styleName"); ++ if (variant.isValid()) { ++ onThemeStyleChange(variant.toString()); ++ } ++ } ++} ++ ++void DiskHistoryWidget::themeChangedSlot(const QString &key) ++{ ++ if (key == "styleName") { ++ auto variant = m_pStyleSettings->get("styleName"); ++ if (variant.isValid()) { ++ onThemeStyleChange(variant.toString()); ++ } ++ } else if("systemFont" == key || "systemFontSize" == key) { ++ auto variant = m_pStyleSettings->get(FONT_SIZE); ++ if (variant.isValid()) { ++ m_curFontSize = m_pStyleSettings->get(FONT_SIZE).toString().toFloat(); ++ onThemeFontChange(m_curFontSize); ++ } ++ } ++} ++ ++void DiskHistoryWidget::onThemeFontChange(float fFontSize) ++{ ++ QFont fontContext; ++ fontContext.setPointSize(fFontSize*0.8); ++ QFont fontTitle = this->font(); ++ if (m_pReadValueLabel) { ++ m_pReadValueLabel->setFont(fontContext); ++ } ++ if (m_pWriteValueLabel) { ++ m_pWriteValueLabel->setFont(fontContext); ++ } ++ if (m_pDiskTitleLabel) { ++ m_pDiskTitleLabel->setFont(fontTitle); ++ } ++ if (m_pReadTitleLabel) { ++ m_pReadTitleLabel->setFont(fontTitle); ++ } ++ if (m_pWriteTitleLabel) { ++ m_pWriteTitleLabel->setFont(fontTitle); ++ } ++} ++ ++void DiskHistoryWidget::onUpdateDiskData() ++{ ++ double allReadSpeed = 0; ++ double allWriteSpeed = 0; ++ QStringList diskList = diskInfo::getDiskName(); ++ foreach (QString diskName, diskList) { ++ DiskSpeedInfo::instance()->updateDiskSpeed(diskName); ++ double readSpeed = DiskSpeedInfo::instance()->readSpeed(diskName); ++ double writeSpeed = DiskSpeedInfo::instance()->writeSpeed(diskName); ++ allReadSpeed += readSpeed; ++ allWriteSpeed += writeSpeed; ++ } ++ ++ m_pReadValueLabel->setText(commom::format::Format_Memory(allReadSpeed, KDK_KILOBYTE) + "/s"); ++ m_pWriteValueLabel->setText(commom::format::Format_Memory(allWriteSpeed, KDK_KILOBYTE) + "/s"); ++} ++ ++void DiskHistoryWidget::onThemeStyleChange(QString strStyleName) ++{ ++ QPalette controlPE; ++ if(strStyleName == "ukui-dark" || strStyleName == "ukui-black") { ++ controlPE.setColor(QPalette::WindowText,QColor("#999999")); ++ m_colorBg = QColor("#262626"); ++ m_pReadTitleLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(56,56,56,100%);color:white;}"); ++ m_pReadValueLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(56,56,56,100%);color:white;}"); ++ m_pWriteTitleLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(56,56,56,100%);color:white;}"); ++ m_pWriteValueLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(56,56,56,100%);color:white;}"); ++ } else { ++ controlPE.setColor(QPalette::WindowText,QColor("#757575")); ++ m_colorBg = QColor("#F5F5F5"); ++ m_pReadTitleLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(245,245,245,100%);color:black;}"); ++ m_pReadValueLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(245,245,245,100%);color:black;}"); ++ m_pWriteTitleLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(245,245,245,100%);color:black;}"); ++ m_pWriteValueLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:rgb(245,245,245,100%);color:black;}"); ++ } ++ if (m_pReadTitleLabel) { ++ m_pReadTitleLabel->setPalette(controlPE); ++ } ++ if (m_pReadValueLabel) { ++ m_pReadValueLabel->setPalette(controlPE); ++ } ++ if (m_pWriteTitleLabel) { ++ m_pWriteTitleLabel->setPalette(controlPE); ++ } ++ if (m_pWriteValueLabel) { ++ m_pWriteValueLabel->setPalette(controlPE); ++ } ++ repaint(); ++} ++ ++ ++void DiskHistoryWidget::mousePressEvent(QMouseEvent *event) ++{ ++ if (event->button() == Qt::LeftButton) { ++ Q_EMIT clicked(); ++ } ++ QWidget::mousePressEvent(event); ++} ++ ++void DiskHistoryWidget::paintEvent(QPaintEvent *event) ++{ ++ QPainterPath path; ++ ++ QPainter painter(this); ++ painter.setOpacity(0.4); ++ painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; ++ painter.setClipping(true); ++ painter.setPen(Qt::transparent); ++ ++ path.addRoundedRect(this->rect(), 4, 4); ++ path.setFillRule(Qt::WindingFill); ++ painter.setBrush(QBrush(m_colorBg)); ++ painter.setPen(Qt::transparent); ++ ++ painter.drawPath(path); ++ QWidget::paintEvent(event); ++} +diff --git a/src/sysresource/diskhistorywidget.h b/src/sysresource/diskhistorywidget.h +new file mode 100755 +index 0000000..58a7eaf +--- /dev/null ++++ b/src/sysresource/diskhistorywidget.h +@@ -0,0 +1,54 @@ ++#ifndef DISKHISTORYWIDGET_H ++#define DISKHISTORYWIDGET_H ++ ++#include <QWidget> ++#include <QHBoxLayout> ++#include <QLabel> ++#include <QGSettings> ++#include <QMouseEvent> ++#include "../controls/klabel.h" ++ ++class DiskHistoryWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ explicit DiskHistoryWidget(QWidget *parent = nullptr); ++ ~DiskHistoryWidget(); ++ ++protected: ++ void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; ++ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; ++ ++private: ++ void initUI(); ++ ++ void initStyleTheme(); ++ void onThemeStyleChange(QString strStyleName); ++ void onThemeFontChange(float fFontSize); ++ ++private: ++ float m_curFontSize; ++ QColor m_colorBg; ++ QGSettings *m_pStyleSettings = nullptr; ++ ++ ++ QVBoxLayout *m_pMainVLayout = nullptr; ++ QHBoxLayout *m_pReadHLayout = nullptr; ++ QHBoxLayout *m_pWriteHLayout = nullptr; ++ KLabel *m_pDiskTitleLabel = nullptr; ++ QLabel *m_pIconReadLabel = nullptr; ++ QLabel *m_pIconWriteLabel = nullptr; ++ KLabel *m_pReadTitleLabel = nullptr; ++ KLabel *m_pWriteTitleLabel = nullptr; ++ KLabel *m_pReadValueLabel = nullptr; ++ KLabel *m_pWriteValueLabel = nullptr; ++ ++public slots: ++ void themeChangedSlot(const QString &key); ++ void onUpdateDiskData(); ++ ++signals: ++ void clicked(); ++}; ++ ++#endif // DISKHISTORYWIDGET_H +diff --git a/src/sysresource/diskitemwidget.cpp b/src/sysresource/diskitemwidget.cpp +new file mode 100644 +index 0000000..6be14bd +--- /dev/null ++++ b/src/sysresource/diskitemwidget.cpp +@@ -0,0 +1,145 @@ ++#include "diskitemwidget.h" ++#include "chartviewwidget.h" ++ ++#include <QPen> ++#include <QPainter> ++#include <QPalette> ++#include <QtMath> ++#include <QApplication> ++#include "commoninfo.h" ++ ++const int margin = 6; ++const int spacing = 6; ++const int sectionSize = 6; ++const int TextSpacing = 12; ++ ++DiskItemWidget::DiskItemWidget(QWidget *parent) : QWidget(parent) ++{ ++ m_pDiskChartWidget = new ChartViewWidget(ChartViewWidget::ChartViewTypes::MEM_CHART, this); ++ m_pDiskChartWidget->setData1Color(m_readColor); ++ m_pDiskChartWidget->setData2Color(m_writeColor); ++} ++ ++DiskItemWidget::~DiskItemWidget() ++{ ++ if (m_pDiskChartWidget) { ++ delete m_pDiskChartWidget; ++ m_pDiskChartWidget = nullptr; ++ } ++} ++ ++void DiskItemWidget::updateWidgetGeometry() ++{ ++ QFont font = QApplication::font(); ++ font.setPointSizeF(font.pointSizeF() - 1); ++ int fontHeight = QFontMetrics(font).height(); ++ int curXMargin = margin; ++ m_pDiskChartWidget->setGeometry(curXMargin, fontHeight * 2 + TextSpacing, this->width() - 2 * curXMargin, this->height() - fontHeight * 2 - TextSpacing - margin); ++} ++ ++void DiskItemWidget::fontChanged(const QFont &font) ++{ ++ m_font = font; ++ updateWidgetGeometry(); ++} ++ ++void DiskItemWidget::resizeEvent(QResizeEvent *event) ++{ ++ QWidget::resizeEvent(event); ++ updateWidgetGeometry(); ++} ++ ++void DiskItemWidget::updateData(const QString &deviceName) ++{ ++ m_deviceName = deviceName; ++ ++ double readSpeed = DiskSpeedInfo::instance()->readSpeed(deviceName); ++ double writeSpeed = DiskSpeedInfo::instance()->writeSpeed(deviceName); ++ ++ m_pDiskChartWidget->updateChartDate(writeSpeed, readSpeed); ++ ++ this->update(); ++} ++ ++void DiskItemWidget::activeItemWidget(bool isShow) ++{ ++ m_isActive = isShow; ++ update(); ++} ++ ++void DiskItemWidget::mousePressEvent(QMouseEvent *event) ++{ ++ QWidget::mousePressEvent(event); ++ emit clicked(m_deviceName); ++} ++ ++void DiskItemWidget::paintEvent(QPaintEvent *event) ++{ ++ QWidget::paintEvent(event); ++ ++ int curXMargin = margin; ++ QPainter painter(this); ++ QFont font = QApplication::font(); ++ font.setPointSizeF(font.pointSizeF() - 1); ++ painter.setFont(font); ++ painter.setRenderHint(QPainter:: Antialiasing, true); ++ ++ const QPalette &palette = QPalette(); ++ ++ int deviceNameWidth = painter.fontMetrics().width(m_deviceName); ++ int deviceNameHeight = painter.fontMetrics().height(); ++ QRect devtitleRect(curXMargin, margin, deviceNameWidth, deviceNameHeight); ++ ++ const QColor &textColor = palette.color(QPalette::Text); ++ if (m_isActive && m_mode == TITLE_VERTICAL) { ++ painter.setPen(Qt::NoPen); ++ QColor selectColor = palette.color(QPalette::Highlight); ++ selectColor.setAlphaF(0.1); ++ ++ painter.setBrush(selectColor); ++ painter.drawRoundedRect(rect(), 8, 8); ++ ++ painter.setPen(palette.color(QPalette::Highlight)); ++ } else { ++ painter.setPen(textColor); ++ } ++ painter.drawText(devtitleRect, Qt::AlignLeft | Qt::AlignVCenter, m_deviceName); ++ painter.setPen(textColor); ++ ++ QString readTitle = QString("%1 %2") ++ .arg(tr("Disk Read")) ++ .arg(DiskSpeedInfo::instance()->readSpeedStr(m_deviceName)); ++ ++ QString writeTitle = QString("%1 %2") ++ .arg(tr("Disk Write")) ++ .arg(DiskSpeedInfo::instance()->writeSpeedStr(m_deviceName)); ++ int readTitleWidth = painter.fontMetrics().width(readTitle); ++ int readTitleHeight = painter.fontMetrics().height(); ++ ++ painter.setPen(Qt::NoPen); ++ painter.setBrush(m_readColor); ++ ++ QRect readStrRect(devtitleRect.left() + spacing + sectionSize, devtitleRect.y() + deviceNameHeight, readTitleWidth, readTitleHeight); ++ painter.drawEllipse(devtitleRect.left(), readStrRect.y() + qCeil((readStrRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); // 读硬盘速度的颜色提示 ++ painter.setPen(palette.color(QPalette::Text)); ++ painter.drawText(readStrRect, Qt::AlignLeft | Qt::AlignVCenter, readTitle); ++ ++ painter.setPen(Qt::NoPen); ++ painter.setBrush(m_writeColor); ++ ++ QRect writeStrRect(devtitleRect.left() + spacing + sectionSize, readStrRect.y() + readTitleHeight, painter.fontMetrics().width(writeTitle), painter.fontMetrics().height()); ++ painter.drawEllipse(devtitleRect.left(), writeStrRect.y() + qCeil((writeStrRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); // 写硬盘速度的颜色提示 ++ painter.setPen(palette.color(QPalette::Text)); ++ painter.drawText(writeStrRect, Qt::AlignLeft | Qt::AlignVCenter, writeTitle); ++} ++ ++void DiskItemWidget::setMode(int mode) ++{ ++ m_mode = mode; ++ this->update(); ++} ++ ++bool DiskItemWidget::isActiveItem() ++{ ++ return m_isActive; ++} +diff --git a/src/sysresource/diskitemwidget.h b/src/sysresource/diskitemwidget.h +new file mode 100644 +index 0000000..952c0a4 +--- /dev/null ++++ b/src/sysresource/diskitemwidget.h +@@ -0,0 +1,54 @@ ++#ifndef DISKITEMWIDGET_H ++#define DISKITEMWIDGET_H ++ ++#include <QObject> ++#include <QWidget> ++ ++class ChartViewWidget; ++ ++class DiskItemWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ enum TitleStyle { ++ TITLE_HORIZONTAL = 0,// 单个模式 ++ TITLE_VERTICAL = 1 // 多个模式 ++ }; ++ ++ explicit DiskItemWidget(QWidget *parent = nullptr); ++ ~DiskItemWidget(); ++ ++signals: ++ void clicked(const QString &deviceName); ++ ++protected: ++ void paintEvent(QPaintEvent *event) override; ++ void resizeEvent(QResizeEvent *event) override; ++ void mousePressEvent(QMouseEvent *event) override; ++ ++public slots: ++ void fontChanged(const QFont &font); ++ void activeItemWidget(bool isShow); ++ ++public: ++ void updateData(const QString &deviceName); ++ void setMode(int mode); ++ bool isActiveItem(); ++ ++private: ++ void updateWidgetGeometry(); ++ ++private: ++ int m_mode = TITLE_HORIZONTAL; ++ QColor m_readColor {"#3790FA"}; ++ QColor m_writeColor {"#F1852B"}; ++ ChartViewWidget *m_pDiskChartWidget; ++ ++ QFont m_font; ++ QString m_deviceName; ++ QList<qreal> m_listWriteSpeed; ++ QList<qreal> m_listReadSpeed; ++ bool m_isActive = false; ++}; ++ ++#endif // DISKITEMWIDGET_H +diff --git a/src/sysresource/diskviewscrollarea.cpp b/src/sysresource/diskviewscrollarea.cpp +new file mode 100644 +index 0000000..d60a7e3 +--- /dev/null ++++ b/src/sysresource/diskviewscrollarea.cpp +@@ -0,0 +1,195 @@ ++#include "diskviewscrollarea.h" ++#include "diskitemwidget.h" ++#include <QThread> ++#include <QGridLayout> ++#include <QTimer> ++#include <QDebug> ++ ++#include "commoninfo.h" ++ ++const int itemSpace = 6; ++ ++DiskViewScrollArea::DiskViewScrollArea(QWidget *parent) : QScrollArea(parent) ++{ ++ m_pCentralWidget = new QWidget(this); ++ this->setWidget(m_pCentralWidget); ++ this->setFrameShape(QFrame::NoFrame); ++ ++ onUpdateData(); ++} ++ ++QString DiskViewScrollArea::getCurrentDiskName() ++{ ++ return m_diskName; ++} ++ ++void DiskViewScrollArea::resizeEvent(QResizeEvent *event) ++{ ++ QScrollArea::resizeEvent(event); ++ updateWidgetGeometry(); ++} ++ ++void DiskViewScrollArea::fontChanged(const QFont &font) ++{ ++ for (int i = 0; i < m_listBlockItemWidget.size(); ++i) { ++ m_listBlockItemWidget[i]->fontChanged(font); ++ } ++} ++ ++void DiskViewScrollArea::updateWidgetGeometry() ++{ ++ int deviceCount = m_listDevice.size(); ++ if (deviceCount <= 0) { ++ return ; ++ } ++ ++ if (deviceCount == 1) { ++ showItemOne(); ++ } else if (deviceCount == 2) { ++ showItemTwo(); ++ } else if (deviceCount > 2) { ++ showItemLgTwo(deviceCount); ++ } ++} ++ ++void DiskViewScrollArea::onSetItemStatus(const QString &deviceName) ++{ ++ for (auto it = m_mapDeviceItemWidget.begin(); it != m_mapDeviceItemWidget.end(); ++it) { ++ it.value()->activeItemWidget(it.key() == deviceName); ++ } ++ m_diskName = deviceName; ++ emit changeInfo(deviceName); ++} ++ ++void DiskViewScrollArea::showItemOne() ++{ ++ DiskItemWidget *item = m_listBlockItemWidget.at(0); ++ item->updateData(m_listDevice.at(0)); ++ item->setMode(DiskItemWidget::TITLE_HORIZONTAL); ++ item->show(); ++ ++ m_mapDeviceItemWidget.insert(m_listDevice.at(0), item); ++ ++ item->setGeometry(0, 0, this->width(), this->height()); ++ item->activeItemWidget(true); ++ ++ m_pCentralWidget->setFixedSize(this->width(), this->height()); ++ ++ for (int i = 1 ; i < m_listBlockItemWidget.size(); i++) { ++ m_listBlockItemWidget.at(i)->hide(); ++ m_listBlockItemWidget.at(i)->setMode(DiskItemWidget::TITLE_HORIZONTAL); ++ } ++ emit changeInfo(m_listDevice.at(0)); ++} ++ ++void DiskViewScrollArea::showItemTwo() ++{ ++ int avgWidth = (this->width() - itemSpace) / 2; ++ int avgheight = this->height(); ++ ++ DiskItemWidget *item1 = m_listBlockItemWidget.at(0); ++ DiskItemWidget *item2 = m_listBlockItemWidget.at(1); ++ item1->show(); ++ item2->show(); ++ ++ item1->updateData(m_listDevice.at(0)); ++ item2->updateData(m_listDevice.at(1)); ++ ++ item1->setMode(DiskItemWidget::TITLE_VERTICAL); ++ item2->setMode(DiskItemWidget::TITLE_VERTICAL); ++ ++ m_mapDeviceItemWidget.insert(m_listDevice.at(0), item1); ++ m_mapDeviceItemWidget.insert(m_listDevice.at(1), item2); ++ ++ item1->setGeometry(0, 0, avgWidth, avgheight); ++ item2->setGeometry(item1->geometry().right() + itemSpace, 0, avgWidth, avgheight); ++ ++ if (!item1->isActiveItem() && !item2->isActiveItem()) { ++ item1->activeItemWidget(true); ++ } ++ ++ m_pCentralWidget->setFixedSize(this->width(), this->height()); ++ ++ bool haveSelect = false; ++ for (int i = 2 ; i < m_listBlockItemWidget.size(); i++) { ++ m_listBlockItemWidget.at(i)->hide(); ++ if (m_listBlockItemWidget.at(i)->isActiveItem()) { ++ haveSelect = true; ++ } ++ m_listBlockItemWidget.at(i)->setMode(DiskItemWidget::TITLE_HORIZONTAL); ++ } ++ ++ if (haveSelect) { ++ m_listBlockItemWidget.at(0)->activeItemWidget(true); ++ emit changeInfo(m_listDevice.at(0)); ++ } ++} ++ ++void DiskViewScrollArea::showItemLgTwo(int count) ++{ ++ int totalPage = qMax(0, (count - 1) / 4); ++ int itemWidth = (this->width() - itemSpace) / 2;; ++ int itemHeight = this->height() / 2; ++ ++ bool noSelect = true; ++ for (int i = 0 ; i < count; i++) { ++ int page = i / 4; ++ DiskItemWidget *itemWidget = m_listBlockItemWidget.at(i); ++ itemWidget->setMode(DiskItemWidget::TITLE_VERTICAL); ++ itemWidget->show(); ++ ++ m_mapDeviceItemWidget.insert(m_listDevice.at(i), itemWidget); ++ if (i % 4 == 0) { ++ itemWidget->setGeometry(page * this->width(), 0, itemWidth, itemHeight); ++ } else if (i % 4 == 1) { ++ itemWidget->setGeometry(page * this->width() + itemWidth + itemSpace, 0, itemWidth, itemHeight); ++ } else if (i % 4 == 2) { ++ itemWidget->setGeometry(page * this->width(), itemHeight, itemWidth, itemHeight); ++ } else if (i % 4 == 3) { ++ itemWidget->setGeometry(page * this->width() + itemWidth + itemSpace, itemHeight, itemWidth, itemHeight); ++ } ++ ++ if (itemWidget->isActiveItem()) { ++ noSelect = false; ++ } ++ itemWidget->updateData(m_listDevice.at(i)); ++ } ++ ++ if (noSelect) { ++ m_listBlockItemWidget.at(0)->activeItemWidget(true); ++ emit changeInfo(m_listDevice.at(0)); ++ } ++ ++ m_pCentralWidget->setFixedSize(this->width() + this->width() * totalPage, this->height()); ++ ++ bool haveSelect = false; ++ for (int i = count ; i < m_listBlockItemWidget.size(); i++) { ++ m_listBlockItemWidget.at(i)->hide(); ++ if (m_listBlockItemWidget.at(i)->isActiveItem()) { ++ haveSelect = true; ++ } ++ m_listBlockItemWidget.at(i)->setMode(DiskItemWidget::TITLE_HORIZONTAL); ++ } ++ ++ if (haveSelect) { ++ m_listBlockItemWidget.at(0)->activeItemWidget(true); ++ emit changeInfo(m_listDevice.at(0)); ++ } ++} ++ ++void DiskViewScrollArea::onUpdateData() ++{ ++ m_listDevice = diskInfo::getDiskName(); ++ qDebug() << "device name list = " << m_listDevice; ++ m_mapDeviceItemWidget.clear(); ++ ++ int deviceCount = m_listDevice.size(); ++ int curItemSize = m_listBlockItemWidget.size(); ++ m_diskName = m_listDevice.at(0); ++ for (int i = 0 ; i < deviceCount - curItemSize; i++) { ++ DiskItemWidget *item = new DiskItemWidget(m_pCentralWidget); ++ m_listBlockItemWidget << item; ++ connect(item, &DiskItemWidget::clicked, this, &DiskViewScrollArea::onSetItemStatus); ++ } ++ updateWidgetGeometry(); ++} +diff --git a/src/sysresource/diskviewscrollarea.h b/src/sysresource/diskviewscrollarea.h +new file mode 100644 +index 0000000..2677213 +--- /dev/null ++++ b/src/sysresource/diskviewscrollarea.h +@@ -0,0 +1,42 @@ ++#ifndef DISKVIEWSCROLLAREA_H ++#define DISKVIEWSCROLLAREA_H ++ ++#include <QMap> ++#include <QScrollArea> ++ ++class DiskItemWidget; ++class DiskViewScrollArea : public QScrollArea ++{ ++ Q_OBJECT ++public: ++ explicit DiskViewScrollArea(QWidget *parent = nullptr); ++ ++ QString getCurrentDiskName(); ++ ++signals: ++ void changeInfo(const QString &deviceName); ++ ++protected: ++ void resizeEvent(QResizeEvent *event) override; ++ ++public slots: ++ void updateWidgetGeometry(); ++ void onUpdateData(); ++ void fontChanged(const QFont &font); ++ void onSetItemStatus(const QString &deviceName); ++ ++private: ++ void showItemOne(); ++ void showItemTwo(); ++ void showItemLgTwo(int count); ++ ++private: ++ QStringList m_listDevice; ++ QList<DiskItemWidget *> m_listBlockItemWidget; ++ QMap<QString, DiskItemWidget *> m_mapDeviceItemWidget; ++ QWidget *m_pCentralWidget; ++ QFont m_font; ++ QString m_diskName; ++}; ++ ++#endif // DISKVIEWSCROLLAREA_H +diff --git a/src/sysresource/netdetailsmodel.cpp b/src/sysresource/netdetailsmodel.cpp +index 4d9e7d3..ae2b5fe 100644 +--- a/src/sysresource/netdetailsmodel.cpp ++++ b/src/sysresource/netdetailsmodel.cpp +@@ -58,7 +58,14 @@ void NetInfoDetailItemDelegate::paint(QPainter *painter, const QStyleOptionViewI + for (int i = 0; i < listKey.count(); ++i) { + // 绘制IPV标题 + QRect titleRect; +- titleRect.setX(textRect.x()); ++ QString language = QLocale::system().name(); ++ // 维吾尔 哈萨克斯 柯尔克孜 语言控件翻转 ++ if (language == "ug_CN" || language == "kk_KZ" || language == "ky_KG") { ++ titleRect.setX(textRect.width() - fm.width(listKey[i])); ++ } else { ++ titleRect.setX(textRect.x()); ++ } ++ + titleRect.setY(textRect.y() + TOPMARGIN + i * fm.height()); + titleRect.setWidth(fm.width(listKey[i])); + titleRect.setHeight(fm.height()); +@@ -66,7 +73,13 @@ void NetInfoDetailItemDelegate::paint(QPainter *painter, const QStyleOptionViewI + + // 绘制IP + QRect valueRect; +- valueRect.setX(textRect.x() + iMaxW + TEXTSPACING); ++ // 维吾尔 哈萨克斯 柯尔克孜 语言控件翻转 ++ if (language == "ug_CN" || language == "kk_KZ" || language == "ky_KG") { ++ valueRect.setX(textRect.width() - iMaxW - TEXTSPACING - fm.width(listValue[i])); ++ } else { ++ valueRect.setX(textRect.x() + iMaxW + TEXTSPACING); ++ } ++ + valueRect.setY(textRect.y() + TOPMARGIN + i * fm.height()); + valueRect.setWidth(fm.width(listValue[i])); + valueRect.setHeight(fm.height()); +diff --git a/src/sysresource/netitemwidget.cpp b/src/sysresource/netitemwidget.cpp +new file mode 100644 +index 0000000..d58e8b5 +--- /dev/null ++++ b/src/sysresource/netitemwidget.cpp +@@ -0,0 +1,158 @@ ++#include "netitemwidget.h" ++ ++#include "chartviewwidget.h" ++#include "commoninfo.h" ++//#include "system/netif.h" ++ ++#include <QtMath> ++#include <QPainter> ++ ++#include <QApplication> ++ ++const int margin = 6; ++const int spacing = 6; ++const int sectionSize = 6; ++const int TextSpacing = 12; ++ ++//DWIDGET_USE_NAMESPACE ++NetItemWidget::NetItemWidget(QWidget *parent, const QString &mac) : QWidget(parent) ++{ ++ m_ifname = mac; ++ ++ m_ChartWidget = new ChartViewWidget(ChartViewWidget::ChartViewTypes::NET_CHART, this); ++ m_ChartWidget->setData1Color(m_recvColor); ++ m_ChartWidget->setData2Color(m_sentColor); ++ updateWidgetGeometry(); ++} ++ ++void NetItemWidget::paintEvent(QPaintEvent *event) ++{ ++ QWidget::paintEvent(event); ++ ++ int curXMargin = m_mode == TITLE_HORIZONTAL ? 0 : margin; ++ QPainter painter(this); ++ painter.setRenderHint(QPainter::Antialiasing, true); ++ painter.setFont(m_font); ++ ++ const QPalette &palette = QPalette(); ++ ++ const QColor &textColor = palette.color(QPalette::Text); ++ if (m_isActive) { ++ painter.setPen(Qt::NoPen); ++ QColor selectColor = palette.color(QPalette::Highlight); ++ selectColor.setAlphaF(0.1); ++ ++ painter.setBrush(selectColor); ++ painter.drawRoundedRect(rect(), 8, 8); ++ ++ painter.setPen(palette.color(QPalette::Highlight)); ++ } else { ++ painter.setPen(textColor); ++ } ++ ++ QRect ifnameRect(curXMargin, margin / 2, painter.fontMetrics().width(m_ifname), painter.fontMetrics().height()); ++ painter.drawText(ifnameRect, Qt::AlignLeft | Qt::AlignVCenter, m_ifname); ++ ++ painter.setPen(textColor); ++ if (m_mode == TITLE_HORIZONTAL) { ++ QString strLeftBrackets = "("; ++ QRect leftBracketsRect(ifnameRect.right() + spacing, ifnameRect.y(), painter.fontMetrics().width(strLeftBrackets), painter.fontMetrics().height()); ++ painter.drawText(leftBracketsRect, Qt::AlignLeft | Qt::AlignVCenter, strLeftBrackets); ++ ++ QString strRecvData = tr("Receive"); ++ strRecvData = strRecvData + " " + m_recv_bps; ++ QRect recvRect(leftBracketsRect.right() + spacing * 2 + sectionSize, ifnameRect.y(), painter.fontMetrics().width(strRecvData), painter.fontMetrics().height()); ++ painter.drawText(recvRect, Qt::AlignLeft | Qt::AlignVCenter, strRecvData); ++ ++ QString strSentData = tr("Send"); ++ strSentData = strSentData + " " + m_sent_bps + " )"; ++ QRect sentRect(sectionSize + recvRect.right() + 3 * spacing, ifnameRect.y(), painter.fontMetrics().width(strSentData), painter.fontMetrics().height()); ++ painter.drawText(sentRect, Qt::AlignLeft | Qt::AlignVCenter, strSentData); ++ ++ painter.setPen(Qt::NoPen); ++ painter.setBrush(m_recvColor); ++ painter.drawEllipse(leftBracketsRect.right() + spacing, leftBracketsRect.y() + qCeil((leftBracketsRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ ++ painter.setBrush(m_sentColor); ++ painter.drawEllipse(recvRect.right() + 2 * spacing, recvRect.y() + qCeil((recvRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ } else { ++ ++ QString strRecvData = tr("Receive"); ++ strRecvData = strRecvData + " " + m_recv_bps; ++ QRect recvRect(margin + spacing + sectionSize, ifnameRect.bottom(), painter.fontMetrics().width(strRecvData), painter.fontMetrics().height()); ++ painter.drawText(recvRect, Qt::AlignLeft | Qt::AlignVCenter, strRecvData); ++ ++ QString strSentData = tr("Send"); ++ strSentData = strSentData + " " + m_sent_bps; ++ QRect sentRect(margin + spacing + sectionSize, recvRect.bottom(), painter.fontMetrics().width(strSentData), painter.fontMetrics().height()); ++ painter.drawText(sentRect, Qt::AlignLeft | Qt::AlignVCenter, strSentData); ++ ++ ++ painter.setPen(Qt::NoPen); ++ painter.setBrush(m_recvColor); ++ painter.drawEllipse(margin, recvRect.y() + qCeil((recvRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ ++ painter.setBrush(m_sentColor); ++ painter.drawEllipse(margin, sentRect.y() + qCeil((sentRect.height() - sectionSize) / 2.0), sectionSize, sectionSize); ++ } ++} ++ ++void NetItemWidget::resizeEvent(QResizeEvent *event) ++{ ++ QWidget::resizeEvent(event); ++ updateWidgetGeometry(); ++} ++ ++void NetItemWidget::mousePressEvent(QMouseEvent *event) ++{ ++ QWidget::mousePressEvent(event); ++ emit clicked(m_ifname); ++} ++ ++void NetItemWidget::fontChanged(const QFont &font) ++{ ++ m_font = font; ++ this->setFont(m_font); ++ updateWidgetGeometry(); ++} ++ ++void NetItemWidget::setMode(int mode) ++{ ++ m_mode = mode; ++ this->update(); ++} ++ ++void NetItemWidget::updateData(const NetifInfo &netifInfo) ++{ ++ // 更新图表 ++ m_ChartWidget->updateChartDate(netifInfo.sendBytes, netifInfo.receiveBytes); ++ ++ if (!netifInfo.netName.isEmpty()) { ++ m_ifname = netifInfo.netName; ++ } ++ ++ m_recv_bps = commom::format::formatNetworkBrandWidth(netifInfo.receiveBytes, false); ++ m_sent_bps = commom::format::formatNetworkBrandWidth(netifInfo.sendBytes, false); ++ ++ this->update(); ++} ++ ++void NetItemWidget::updateActiveStatus(bool active) ++{ ++ m_isActive = active; ++ update(); ++} ++ ++void NetItemWidget::updateWidgetGeometry() ++{ ++ QFont ft1; ++ ft1.setPixelSize(14); ++ m_font = ft1; ++ int fontHeight = QFontMetrics(m_font).height(); ++ int curXMargin = m_mode == TITLE_HORIZONTAL ? 0 : margin; ++ if (m_mode == TITLE_HORIZONTAL) { ++ m_ChartWidget->setGeometry(curXMargin, TextSpacing, this->width() - 2 * curXMargin, this->height() - TextSpacing - margin); ++ } else { ++ m_ChartWidget->setGeometry(curXMargin, fontHeight * 2 + TextSpacing, this->width() - 2 * curXMargin, this->height() - fontHeight * 2 - TextSpacing - margin); ++ } ++} +diff --git a/src/sysresource/netitemwidget.h b/src/sysresource/netitemwidget.h +new file mode 100644 +index 0000000..175acfc +--- /dev/null ++++ b/src/sysresource/netitemwidget.h +@@ -0,0 +1,60 @@ ++#ifndef NETITEMWIDGET_H ++#define NETITEMWIDGET_H ++ ++#include <QWidget> ++#include <memory> ++ ++typedef struct NetifInfo ++{ ++ float receiveBytes; ++ float sendBytes; ++ QString netName; ++} NetifInfo; ++ ++class ChartViewWidget; ++class NetItemWidget : public QWidget ++{ ++ Q_OBJECT ++public: ++ enum TitleStyle { ++ TITLE_HORIZONTAL = 0,// 单个模式 ++ TITLE_VERTICAL = 1 // 多个模式 ++ }; ++ ++ explicit NetItemWidget(QWidget *parent = nullptr, const QString &mac = ""); ++ ++public: ++ void updateActiveStatus(bool active); ++ void setMode(int mode); ++ ++protected: ++ void paintEvent(QPaintEvent *event); ++ void resizeEvent(QResizeEvent *event); ++ void mousePressEvent(QMouseEvent *event); ++ ++signals: ++ void clicked(const QString &mac); ++ ++public slots: ++ void fontChanged(const QFont &font); ++ void updateData(const NetifInfo &netifInfo); ++ ++private: ++ void updateWidgetGeometry(); ++ ++private: ++ int m_mode = TITLE_HORIZONTAL; ++ QColor m_recvColor {"#B37FEB"}; ++ QColor m_sentColor {"#FF7875"}; ++ ++ QString m_ifname; // 网卡名称 ++ QString m_recv_bps; // 接受速率 ++ QString m_sent_bps; // 发送速率 ++ ChartViewWidget *m_ChartWidget; ++ ++ QFont m_font; ++ bool m_isActive = false; // 是否被点击 ++}; ++ ++#endif // NETITEMWIDGET_H ++ +diff --git a/src/sysresource/netviewscrollarea.cpp b/src/sysresource/netviewscrollarea.cpp +index f44e742..64d5acc 100644 +--- a/src/sysresource/netviewscrollarea.cpp ++++ b/src/sysresource/netviewscrollarea.cpp +@@ -1,5 +1,8 @@ + #include "netviewscrollarea.h" + #include <QDebug> ++ ++#include "commoninfo.h" ++ + #include "kysdk/kysdk-system/libkync.h" + #include <kysdk/kysdk-system/libkyrealtimeinfo.h> + +@@ -38,8 +41,8 @@ void NetViewScrollArea::resizeEvent(QResizeEvent *event) + void NetViewScrollArea::fontChanged(const QFont &font) + { + for (auto iter = m_mapItemView.begin(); iter != m_mapItemView.end(); iter++) { +- ChartViewWidget *itemView = iter.value(); +-// itemView->fontChanged(font); ++ NetItemWidget *itemView = iter.value(); ++ itemView->fontChanged(font); + } + } + +@@ -83,17 +86,18 @@ void NetViewScrollArea::onModelUpdate() + netinfo1[i].last_out = out; + netinfo1[i].time = time; + +- long long int receiveBytes = din; +- long long int sendBytes = dout; +- ++ NetifInfo netifInfo; ++ netifInfo.receiveBytes = din; ++ netifInfo.sendBytes = dout; ++ netifInfo.netName = mac; + if (!m_mapItemView.contains(mac)) { +- ChartViewWidget *itemWidget = new ChartViewWidget(mac, m_centralWidget); +- connect(itemWidget, &ChartViewWidget::clicked, this, &NetViewScrollArea::onSetItemActiveStatus); +- itemWidget->updateDate(sendBytes/1024, receiveBytes/1024); ++ NetItemWidget *itemWidget = new NetItemWidget(m_centralWidget, netifInfo.netName); ++ connect(itemWidget, &NetItemWidget::clicked, this, &NetViewScrollArea::onSetItemActiveStatus); ++ itemWidget->updateData(netifInfo); + m_mapItemView.insert(mac, itemWidget); + } else { +- ChartViewWidget *itemWidget = m_mapItemView.value(mac); +- itemWidget->updateDate(sendBytes/1024, receiveBytes/1024); ++ NetItemWidget *itemWidget = m_mapItemView.value(mac); ++ itemWidget->updateData(netifInfo); + } + } + +@@ -112,9 +116,9 @@ void NetViewScrollArea::onModelUpdate() + + if (netifCnt > 0 && !cardlist.contains(m_currentMac)) { + if (cardlist.size() == 1) { +- m_mapItemView.value(m_mapItemView.begin().key())->setActive(false); ++ m_mapItemView.value(m_mapItemView.begin().key())->updateActiveStatus(false); + } else { +- m_mapItemView.value(m_mapItemView.begin().key())->setActive(true); ++ m_mapItemView.value(m_mapItemView.begin().key())->updateActiveStatus(true); + } + m_currentMac = m_mapItemView.begin().key(); + emit netifItemClicked(m_mapItemView.begin().key()); +@@ -128,13 +132,12 @@ void NetViewScrollArea::onSetItemActiveStatus(const QString &mac) + m_currentMac = mac.toUtf8(); + + for (auto iter = m_mapItemView.begin(); iter != m_mapItemView.end(); iter++) { +- ChartViewWidget *itemView = iter.value(); ++ NetItemWidget *itemView = iter.value(); + if (netCount > 1 && iter.key() == mac) { +- +- itemView->setActive(true); ++ itemView->updateActiveStatus(true); + emit netifItemClicked(mac); + } else { +- itemView->setActive(false); ++ itemView->updateActiveStatus(false); + } + } + } +@@ -154,15 +157,15 @@ void NetViewScrollArea::updateWidgetGeometry() + void NetViewScrollArea::showItemOnlyeOne() + { + for (auto iter = m_mapItemView.begin(); iter != m_mapItemView.end(); iter++) { +- ChartViewWidget *itemView = iter.value(); ++ NetItemWidget *itemView = iter.value(); + if (cardlist.contains(iter.key())) { + itemView->show(); +- itemView->setMode(ChartViewWidget::TITLE_HORIZONTAL); ++ itemView->setMode(NetItemWidget::TITLE_HORIZONTAL); + itemView->setGeometry(0, 0, this->width(), this->height()); +- itemView->setActive(false); ++ itemView->updateActiveStatus(false); + } else { + itemView->hide(); +- itemView->setActive(false); ++ itemView->updateActiveStatus(false); + } + } + +@@ -176,18 +179,18 @@ void NetViewScrollArea::showItemDouble() + int itemWidth = (this->width() - itemSpace) / 2; + + for (auto iter = m_mapItemView.begin(); iter != m_mapItemView.end(); iter++) { +- ChartViewWidget *itemView = iter.value(); ++ NetItemWidget *itemView = iter.value(); + if (cardlist.contains(iter.key())) { + itemView->show(); +- itemView->setMode(ChartViewWidget::TITLE_VERTICAL); ++ itemView->setMode(NetItemWidget::TITLE_VERTICAL); + itemView->setGeometry(itemOffsetX, 0, itemWidth, itemHeight); + itemOffsetX = itemOffsetX + itemWidth + itemSpace; + if (iter.key() == m_currentMac) { +- itemView->setActive(true); ++ itemView->updateActiveStatus(true); + } + } else { + itemView->hide(); +- itemView->setActive(false); ++ itemView->updateActiveStatus(false); + } + } + +@@ -201,10 +204,10 @@ void NetViewScrollArea::showItemLgDouble() + int itemCurrentCnt = -1; + int page = 0; + for (auto iter = m_mapItemView.begin(); iter != m_mapItemView.end(); iter++) { +- ChartViewWidget *itemView = iter.value(); ++ NetItemWidget *itemView = iter.value(); + if (cardlist.contains(iter.key())) { + itemCurrentCnt++; +- itemView->setMode(ChartViewWidget::TITLE_VERTICAL); ++ itemView->setMode(NetItemWidget::TITLE_VERTICAL); + itemView->show(); + page = itemCurrentCnt / 4; + if (itemCurrentCnt % 4 == 0) { +@@ -217,11 +220,11 @@ void NetViewScrollArea::showItemLgDouble() + itemView->setGeometry(itemWidth + itemSpace, page * this->height() + itemHeight, itemWidth, itemHeight); + } + if (iter.key() == m_currentMac) { +- itemView->setActive(true); ++ itemView->updateActiveStatus(true); + } + } else { + itemView->hide(); +- itemView->setActive(false); ++ itemView->updateActiveStatus(false); + } + } + m_centralWidget->setFixedSize(this->width(), this->height() + this->height() * page); +diff --git a/src/sysresource/netviewscrollarea.h b/src/sysresource/netviewscrollarea.h +index 4dad46b..bc35898 100644 +--- a/src/sysresource/netviewscrollarea.h ++++ b/src/sysresource/netviewscrollarea.h +@@ -4,7 +4,7 @@ + #include <QScrollArea> + #include <QMap> + +-#include "chartviewwidget.h" ++#include "netitemwidget.h" + + class NetViewScrollArea : public QScrollArea + { +@@ -36,7 +36,7 @@ private: + QWidget *m_centralWidget; + QString m_currentMac = ""; + QStringList cardlist; +- QMultiMap<QString, ChartViewWidget *> m_mapItemView; ++ QMultiMap<QString, NetItemWidget *> m_mapItemView; + }; + + #endif // NETVIEWSCROLLAREA_H +diff --git a/src/translation/ukui-system-monitor_bo_CN.ts b/src/translation/ukui-system-monitor_bo_CN.ts +index d64219a..a6726d7 100644 +--- a/src/translation/ukui-system-monitor_bo_CN.ts ++++ b/src/translation/ukui-system-monitor_bo_CN.ts +@@ -12,16 +12,12 @@ + <context> + <name>ChartViewWidget</name> + <message> +- <location filename="../sysresource/chartviewwidget.cpp" line="118"/> +- <location filename="../sysresource/chartviewwidget.cpp" line="136"/> + <source>Receive</source> +- <translation>བསྡུ་ལེན།</translation> ++ <translation type="vanished">བསྡུ་ལེན།</translation> + </message> + <message> +- <location filename="../sysresource/chartviewwidget.cpp" line="123"/> +- <location filename="../sysresource/chartviewwidget.cpp" line="141"/> + <source>Send</source> +- <translation>སྐྱེལ་སྤྲོད།</translation> ++ <translation type="vanished">སྐྱེལ་སྤྲོད།</translation> + </message> + </context> + <context> +@@ -151,6 +147,73 @@ + <translation>ཕྱིར་འཐེན།</translation> + </message> + </context> ++<context> ++ <name>DiskDetailsModel</name> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="60"/> ++ <source>Model</source> ++ <translation>བཟོ་དབྱིབས།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="62"/> ++ <source>Capacity</source> ++ <translation>ཤོང་ཚད།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="66"/> ++ <source>Read Speed</source> ++ <translation>ཀློག་པའི་མྱུར་ཚད།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="68"/> ++ <source>Write Speed</source> ++ <translation>མྱུར་ཚད་ཀྱི་ནང་དུ་འབྲི་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="72"/> ++ <source>Type</source> ++ <translation>རིགས་དབྱིབས།</translation> ++ </message> ++</context> ++<context> ++ <name>DiskDetailsWidget</name> ++ <message> ++ <location filename="../sysresource/diskdetailswidget.cpp" line="16"/> ++ <source>Disk</source> ++ <translation>ཁབ་ལེན་སྡེར་མ།</translation> ++ </message> ++</context> ++<context> ++ <name>DiskHistoryWidget</name> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="41"/> ++ <source>Disk reading and writing</source> ++ <translation>ཁབ་ལེན་གྱི་སྡེར་མ་ཀློག་པ།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="49"/> ++ <source>Disk Read</source> ++ <translation>ཁབ་ལེན་སྡེར་མ་ཀློག་པ།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="61"/> ++ <source>Disk Write</source> ++ <translation>ཁབ་ལེན་སྡེར་མའི་ནང་དུ་བྲིས་པ།</translation> ++ </message> ++</context> ++<context> ++ <name>DiskItemWidget</name> ++ <message> ++ <location filename="../sysresource/diskitemwidget.cpp" line="110"/> ++ <source>Disk Read</source> ++ <translation>ཁབ་ལེན་སྡེར་མ་ཀློག་པ།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskitemwidget.cpp" line="114"/> ++ <source>Disk Write</source> ++ <translation>ཁབ་ལེན་སྡེར་མའི་ནང་དུ་བྲིས་པ།</translation> ++ </message> ++</context> + <context> + <name>FileSystemInfoItem</name> + <message> +@@ -262,15 +325,15 @@ + <translation type="vanished">འཚོལ་ཞིབ།</translation> + </message> + <message> +- <location filename="../krightwidget.cpp" line="216"/> +- <location filename="../krightwidget.cpp" line="228"/> ++ <location filename="../krightwidget.cpp" line="223"/> ++ <location filename="../krightwidget.cpp" line="235"/> + <source>Restore</source> + <translation>སླར་གསོ་བྱེད་པ།</translation> + </message> + <message> + <location filename="../krightwidget.cpp" line="86"/> +- <location filename="../krightwidget.cpp" line="219"/> +- <location filename="../krightwidget.cpp" line="231"/> ++ <location filename="../krightwidget.cpp" line="226"/> ++ <location filename="../krightwidget.cpp" line="238"/> + <source>Maximize</source> + <translation>ཚད་གཞི་མཐོ་ཤོས་ཀྱི་སྒོ་ནས</translation> + </message> +@@ -283,35 +346,40 @@ + <translation>ཅིན་ལིན་མ་ལག་ལྟ་ཞིབ་ཚད་ལེན</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="193"/> ++ <location filename="../mainwindow.cpp" line="196"/> + <source>Processes</source> + <translation>བཟོ་རྩལ།</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="198"/> ++ <location filename="../mainwindow.cpp" line="201"/> + <source>Services</source> + <translation>ཞབས་ཞུ།</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="202"/> ++ <location filename="../mainwindow.cpp" line="205"/> + <source>Disks</source> + <translation>ཁབ་ལེན་གྱི་ཁབ་ལེན་འཁོར་ལོ།</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="205"/> ++ <location filename="../mainwindow.cpp" line="208"/> + <source>Cpu Details</source> + <translation>Cpuཞིབ་ཕྲ།</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="208"/> ++ <location filename="../mainwindow.cpp" line="211"/> + <source>Mem Details</source> + <translation>ནང་གསོག་གི་གནས་ཚུལ་ཞིབ་ཕྲ།</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="211"/> ++ <location filename="../mainwindow.cpp" line="214"/> + <source>Net Details</source> + <translation>དྲ་རྒྱའི་གནས་ཚུལ་ཞིབ་ཕྲ།</translation> + </message> ++ <message> ++ <location filename="../mainwindow.cpp" line="217"/> ++ <source>Disk Details</source> ++ <translation>ཁབ་ལེན་སྡེར་མའི་གནས་ཚུལ་ཞིབ་ཕྲ།</translation> ++ </message> + </context> + <context> + <name>MemDetailsModel</name> +@@ -408,13 +476,13 @@ + <translation>དྲན་ཤེས་</translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="133"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="132"/> + <source>Swap</source> + <translation>བརྗེ་རེས་བྱེད་པ།</translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="138"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="285"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="137"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="297"/> + <source>Not enabled</source> + <translation>ནུས་པ་ཐོན་མི་ཐུབ་པ།</translation> + </message> +@@ -422,109 +490,109 @@ + <context> + <name>NetDetailsModel</name> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="138"/> +- <location filename="../sysresource/netdetailsmodel.cpp" line="140"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="151"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="153"/> + <source>IPv4</source> + <translation>IPv4</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="151"/> +- <location filename="../sysresource/netdetailsmodel.cpp" line="153"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="164"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="166"/> + <source>IPv6</source> + <translation>IPv6</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="161"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="174"/> + <source>Connection type</source> + <translation>འབྲེལ་མཐུད་རིགས།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="168"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="181"/> + <source>ESSID</source> + <translation>དྲ་རྒྱའི་མིང་།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="173"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="186"/> + <source>Link quality</source> + <translation>བརྡ་རྟགས་སྤུས་ཚད།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="178"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="191"/> + <source>Signal strength</source> + <translation>བརྡ་རྟགས་ཡང་བ།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="183"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="196"/> + <source>Noise level</source> + <translation>སྒྲ།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="189"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="202"/> + <source>MAC</source> + <translation>MAC</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="194"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="207"/> + <source>Bandwidth</source> + <translation>འགྲོས་ཚད།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="199"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="212"/> + <source>RX packets</source> + <translation>བསྡུ་ལེན་ཁུག་མའི་གྲངས་འབོར།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="204"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="217"/> + <source>RX bytes</source> + <translation>བསྡོམས་རྩིས།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="209"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="222"/> + <source>RX errors</source> + <translation>བསྡུ་ལེན།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="214"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="227"/> + <source>RX dropped</source> + <translation>བསྡུ་ལེན།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="219"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="232"/> + <source>RX overruns</source> + <translation>FIFOདང་ལེན་བྱས།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="224"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="237"/> + <source>RX frame</source> + <translation>ཚོ་ཆུང་ལྡེབ་ནོར་བ།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="229"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="242"/> + <source>TX packets</source> + <translation>སྐུར་དངོས་གྲངས་འབོར།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="234"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="247"/> + <source>TX bytes</source> + <translation>བསྡོམས་པས་བསྐུར་ཟིན།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="239"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="252"/> + <source>TX errors</source> + <translation>སྐུར་བ།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="244"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="257"/> + <source>TX dropped</source> + <translation>སྐུར་བ།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="249"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="262"/> + <source>TX overruns</source> + <translation>FIFOབསྐུར་རོགས།</translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="254"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="267"/> + <source>TX carrier</source> + <translation>རླབས་ཐེག་ཟད་གྲོན།</translation> + </message> +@@ -550,7 +618,7 @@ + <translation>སྐུར་སྐྱེལ་བྱེད་པ།</translation> + </message> + <message> +- <location filename="../sysresource/nethistorywidget.cpp" line="157"/> ++ <location filename="../sysresource/nethistorywidget.cpp" line="156"/> + <source>Receive</source> + <translation>བསྡུ་ལེན་བྱས་པ།</translation> + </message> +@@ -584,6 +652,21 @@ + <translation>ཁོངས།</translation> + </message> + </context> ++<context> ++ <name>NetItemWidget</name> ++ <message> ++ <location filename="../sysresource/netitemwidget.cpp" line="62"/> ++ <location filename="../sysresource/netitemwidget.cpp" line="80"/> ++ <source>Receive</source> ++ <translation>བསྡུ་ལེན་བྱས་པ།</translation> ++ </message> ++ <message> ++ <location filename="../sysresource/netitemwidget.cpp" line="67"/> ++ <location filename="../sysresource/netitemwidget.cpp" line="85"/> ++ <source>Send</source> ++ <translation>སྐུར་སྐྱེལ་བྱེད་པ།</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -657,114 +740,114 @@ + <context> + <name>ProcessTableView</name> + <message> +- <location filename="../process/processtableview.cpp" line="215"/> ++ <location filename="../process/processtableview.cpp" line="218"/> + <source>No search result</source> + <translation>འཚོལ་ཞིབ་བྱས་འབྲས་མེད་པ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="305"/> +- <location filename="../process/processtableview.cpp" line="644"/> ++ <location filename="../process/processtableview.cpp" line="308"/> + <location filename="../process/processtableview.cpp" line="647"/> +- <location filename="../process/processtableview.cpp" line="739"/> ++ <location filename="../process/processtableview.cpp" line="650"/> ++ <location filename="../process/processtableview.cpp" line="748"/> + <source>End process</source> + <translation>མཇུག་སྒྲིལ་བའི་གོ་རིམ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="307"/> +- <location filename="../process/processtableview.cpp" line="684"/> ++ <location filename="../process/processtableview.cpp" line="310"/> + <location filename="../process/processtableview.cpp" line="687"/> +- <location filename="../process/processtableview.cpp" line="769"/> ++ <location filename="../process/processtableview.cpp" line="690"/> ++ <location filename="../process/processtableview.cpp" line="778"/> + <source>Kill process</source> + <translation>གསོད་པའི་གོ་རིམ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="321"/> ++ <location filename="../process/processtableview.cpp" line="324"/> + <source>Very High</source> + <translation>ཧ་ཅང་མཐོ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="322"/> ++ <location filename="../process/processtableview.cpp" line="325"/> + <source>High</source> + <translation>མཐོ་ཚད།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="323"/> ++ <location filename="../process/processtableview.cpp" line="326"/> + <source>Normal</source> + <translation>རྒྱུན་ལྡན་གྱི་གནས་</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="324"/> ++ <location filename="../process/processtableview.cpp" line="327"/> + <source>Low</source> + <translation>དམའ་བ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="325"/> ++ <location filename="../process/processtableview.cpp" line="328"/> + <source>Very Low</source> + <translation>ཧ་ཅང་དམའ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="326"/> ++ <location filename="../process/processtableview.cpp" line="329"/> + <source>Custom</source> + <translation>གོམས་སྲོལ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="331"/> ++ <location filename="../process/processtableview.cpp" line="334"/> + <source>Change Priority</source> + <translation>སྔོན་ལ་བསྒྱུར་བཅོས་བྱ་དགོས།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="333"/> ++ <location filename="../process/processtableview.cpp" line="336"/> + <source>Properties</source> + <translation>ངོ་བོ་དང་གཟུགས་</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="351"/> ++ <location filename="../process/processtableview.cpp" line="354"/> + <source>User</source> + <translation>སྤྱོད་མཁན།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="357"/> ++ <location filename="../process/processtableview.cpp" line="360"/> + <source>Disk</source> + <translation>ཁབ་ལེན་གྱི་ཁབ་ལེན་</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="363"/> ++ <location filename="../process/processtableview.cpp" line="366"/> + <source>CPU</source> + <translation>སྒྲིག་གཅོད་ཆས་</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="369"/> ++ <location filename="../process/processtableview.cpp" line="372"/> + <source>ID</source> + <translation>ཐོབ་ཐང་ལག་ཁྱེར།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="375"/> ++ <location filename="../process/processtableview.cpp" line="378"/> + <source>Flownet Persec</source> + <translation>དྲ་རྒྱ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="381"/> ++ <location filename="../process/processtableview.cpp" line="384"/> + <source>Memory</source> + <translation>དྲན་ཤེས་</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="387"/> ++ <location filename="../process/processtableview.cpp" line="390"/> + <source>Priority</source> + <translation>སྔོན་ཐོབ་ཀྱི་དོན་དག</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="590"/> +- <location filename="../process/processtableview.cpp" line="594"/> ++ <location filename="../process/processtableview.cpp" line="593"/> ++ <location filename="../process/processtableview.cpp" line="597"/> + <source>Stop process</source> + <translation>བཀག་འགོག་བྱེད་པའི་གོ་རིམ</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="735"/> ++ <location filename="../process/processtableview.cpp" line="744"/> + <source>End the selected process %1 (PID %2) ?</source> + <translation>%1 (PID %2) ཡིས་བདམས་པའི་གོ་རིམ་མཇུག་བསྒྲིལ་དགོས་སམ། ?</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="765"/> ++ <location filename="../process/processtableview.cpp" line="774"/> + <source>Kill the selected process %1 (PID %2) ?</source> + <translation>བདམས་ཟིན་པའི་གོ་རིམ་ %1 (PID %2) བསད་པ་ཡིན་ནམ། ?</translation> + </message> +@@ -773,15 +856,15 @@ + <translation type="vanished">"%1"(PID:%2)ཡིས་བདམས་པའི་གོ་རིམ་མཇུག་བསྒྲིལ་དགོས་སམ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="736"/> ++ <location filename="../process/processtableview.cpp" line="745"/> + <source>Ending a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be ended. + Are you sure to continue?</source> + <translation>བརྒྱུད་རིམ་ཞིག་མཇུག་བསྒྲིལ་ན་གཞི་གྲངས་ལ་གཏོར་བརླག་དང་། ཚོགས་འདུ་གཏོར་བརླག་གཏོང་བའམ་ཡང་ན་བདེ་འཇགས་ཀྱི་ཉེན་ཁ་ འགན་མི་འཁུར་བའི་གོ་རིམ་མ་གཏོགས་མཇུག་བསྒྲིལ་མི་རུང་། + ཁྱོད་ཀྱིས་ད་དུང་མུ་མཐུད་དུ་རྒྱུན་འཁྱོངས་བྱེད་ཐུབ</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="740"/> +- <location filename="../process/processtableview.cpp" line="770"/> ++ <location filename="../process/processtableview.cpp" line="749"/> ++ <location filename="../process/processtableview.cpp" line="779"/> + <source>Cancel</source> + <translation>ཕྱིར་འཐེན།</translation> + </message> +@@ -790,19 +873,19 @@ Are you sure to continue?</source> + <translation type="vanished">བདམས་ཟིན་པའི་གོ་རིམ་"%1"(PID:%2)བསད་པ་ཡིན་ནམ།</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="766"/> ++ <location filename="../process/processtableview.cpp" line="775"/> + <source>Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed. + Are you sure to continue?</source> + <translation>བརྒྱུད་རིམ་ཞིག་བསད་ན་གཞི་གྲངས་མེད་པར་བཟོ་བ་དང་། ཚོགས་འདུ་གཏོར་བརླག་གཏོང་བའམ་ཡང་ན་བདེ་འཇགས་ཀྱི་ཉེན་ཁ་ འགན་མི་འཁུར་བའི་གོ་རིམ་ཁོ་ན་གསོད་དགོས། + ཁྱོད་ཀྱིས་ད་དུང་མུ་མཐུད་དུ་རྒྱུན་འཁྱོངས་བྱེད་ཐུབ</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="782"/> ++ <location filename="../process/processtableview.cpp" line="791"/> + <source>Not allowed operation!</source> + <translation>བཀོལ་སྤྱོད་བྱས་མི་ཆོག</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="783"/> ++ <location filename="../process/processtableview.cpp" line="792"/> + <source>OK</source> + <translation>འགྲིགས།</translation> + </message> +@@ -863,6 +946,7 @@ Are you sure to continue?</source> + </message> + <message> + <location filename="../process/processtablemodel.cpp" line="57"/> ++ <location filename="../sysresource/commoninfo.cpp" line="440"/> + <location filename="../sysresource/memhistorywidget.cpp" line="39"/> + <location filename="../sysresource/nethistorywidget.cpp" line="43"/> + <source>MiB</source> +@@ -890,39 +974,46 @@ Are you sure to continue?</source> + <translation>བར་ཆད་མེད་པ།</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="433"/> + <location filename="../sysresource/memhistorywidget.cpp" line="35"/> + <location filename="../sysresource/nethistorywidget.cpp" line="36"/> + <source>KiB</source> + <translation>KiB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="447"/> + <location filename="../sysresource/memhistorywidget.cpp" line="43"/> + <location filename="../sysresource/nethistorywidget.cpp" line="50"/> + <source>GiB</source> + <translation>GiB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="454"/> + <location filename="../sysresource/memhistorywidget.cpp" line="47"/> + <location filename="../sysresource/nethistorywidget.cpp" line="57"/> + <source>TiB</source> + <translation>TiB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="435"/> + <location filename="../sysresource/nethistorywidget.cpp" line="38"/> + <source>KiB/s</source> + <translation>KB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="442"/> + <location filename="../sysresource/nethistorywidget.cpp" line="45"/> + <source>MiB/s</source> + <translation>MB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="449"/> + <location filename="../sysresource/nethistorywidget.cpp" line="52"/> + <source>GiB/s</source> + <translation>GB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="456"/> + <location filename="../sysresource/nethistorywidget.cpp" line="59"/> + <source>TiB/s</source> + <translation>TB/s</translation> +@@ -991,31 +1082,28 @@ Are you sure to continue?</source> + <context> + <name>ReniceDialog</name> + <message> +- <location filename="../dialog/renicedialog.cpp" line="68"/> +- <location filename="../dialog/renicedialog.cpp" line="300"/> ++ <location filename="../dialog/renicedialog.cpp" line="57"/> + <source>Change Priority of Process %1 (PID: %2)</source> + <translation>བཟོ་རྩལ་གྱི་སྔོན་ཐོབ་དབང་ཆ་བསྒྱུར་བཅོས་བྱ་དགོས། %1 (PID: %2)</translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="86"/> +- <location filename="../dialog/renicedialog.cpp" line="330"/> ++ <location filename="../dialog/renicedialog.cpp" line="61"/> ++ <location filename="../dialog/renicedialog.cpp" line="242"/> + <source>Nice value:</source> + <translation>རིན་ཐང་ཧ་ཅང་ཡག་པོ་</translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="107"/> ++ <location filename="../dialog/renicedialog.cpp" line="80"/> + <source>Note:The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority.</source> + <translation>མཆན་འགྲེལ།:བརྒྱུད་རིམ་ཞིག་གི་སྔོན་ཐོབ་དབང་ཆ་ནི་དེའི་རིན་ཐང་བཟང་པོ་ཡིན། ཅུང་དམའ་བའི་རིན་ཐང་དེ་སྔར་ལས་མཐོ་བའི་སྔོན་ཐོབ་ཀྱི་དོན་དག་དང་མཐུན་པ་རེད།</translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="119"/> +- <location filename="../dialog/renicedialog.cpp" line="310"/> ++ <location filename="../dialog/renicedialog.cpp" line="91"/> + <source>Cancel</source> + <translation>ཕྱིར་འཐེན།</translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="124"/> +- <location filename="../dialog/renicedialog.cpp" line="320"/> ++ <location filename="../dialog/renicedialog.cpp" line="96"/> + <source>Change Priority</source> + <translation>སྔོན་ལ་བསྒྱུར་བཅོས་བྱ་དགོས།</translation> + </message> +diff --git a/src/translation/ukui-system-monitor_en_US.ts b/src/translation/ukui-system-monitor_en_US.ts +index bc7ae81..2c95ef5 100644 +--- a/src/translation/ukui-system-monitor_en_US.ts ++++ b/src/translation/ukui-system-monitor_en_US.ts +@@ -9,21 +9,6 @@ + <translation type="unfinished"></translation> + </message> + </context> +-<context> +- <name>ChartViewWidget</name> +- <message> +- <location filename="../sysresource/chartviewwidget.cpp" line="118"/> +- <location filename="../sysresource/chartviewwidget.cpp" line="136"/> +- <source>Receive</source> +- <translation type="unfinished"></translation> +- </message> +- <message> +- <location filename="../sysresource/chartviewwidget.cpp" line="123"/> +- <location filename="../sysresource/chartviewwidget.cpp" line="141"/> +- <source>Send</source> +- <translation type="unfinished"></translation> +- </message> +-</context> + <context> + <name>CpuDetailsModel</name> + <message> +@@ -151,6 +136,73 @@ + <translation type="unfinished"></translation> + </message> + </context> ++<context> ++ <name>DiskDetailsModel</name> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="60"/> ++ <source>Model</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="62"/> ++ <source>Capacity</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="66"/> ++ <source>Read Speed</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="68"/> ++ <source>Write Speed</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskdetailsmodel.h" line="72"/> ++ <source>Type</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>DiskDetailsWidget</name> ++ <message> ++ <location filename="../sysresource/diskdetailswidget.cpp" line="16"/> ++ <source>Disk</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>DiskHistoryWidget</name> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="41"/> ++ <source>Disk reading and writing</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="49"/> ++ <source>Disk Read</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskhistorywidget.cpp" line="61"/> ++ <source>Disk Write</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> ++<context> ++ <name>DiskItemWidget</name> ++ <message> ++ <location filename="../sysresource/diskitemwidget.cpp" line="110"/> ++ <source>Disk Read</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/diskitemwidget.cpp" line="114"/> ++ <source>Disk Write</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> + <context> + <name>FileSystemInfoItem</name> + <message> +@@ -250,15 +302,15 @@ + <translation type="unfinished">System Monitor</translation> + </message> + <message> +- <location filename="../krightwidget.cpp" line="216"/> +- <location filename="../krightwidget.cpp" line="228"/> ++ <location filename="../krightwidget.cpp" line="223"/> ++ <location filename="../krightwidget.cpp" line="235"/> + <source>Restore</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../krightwidget.cpp" line="86"/> +- <location filename="../krightwidget.cpp" line="219"/> +- <location filename="../krightwidget.cpp" line="231"/> ++ <location filename="../krightwidget.cpp" line="226"/> ++ <location filename="../krightwidget.cpp" line="238"/> + <source>Maximize</source> + <translation type="unfinished"></translation> + </message> +@@ -271,35 +323,40 @@ + <translation type="unfinished">System Monitor</translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="193"/> ++ <location filename="../mainwindow.cpp" line="196"/> + <source>Processes</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="198"/> ++ <location filename="../mainwindow.cpp" line="201"/> + <source>Services</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="202"/> ++ <location filename="../mainwindow.cpp" line="205"/> + <source>Disks</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="205"/> ++ <location filename="../mainwindow.cpp" line="208"/> + <source>Cpu Details</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="208"/> ++ <location filename="../mainwindow.cpp" line="211"/> + <source>Mem Details</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../mainwindow.cpp" line="211"/> ++ <location filename="../mainwindow.cpp" line="214"/> + <source>Net Details</source> + <translation type="unfinished"></translation> + </message> ++ <message> ++ <location filename="../mainwindow.cpp" line="217"/> ++ <source>Disk Details</source> ++ <translation type="unfinished"></translation> ++ </message> + </context> + <context> + <name>MemDetailsModel</name> +@@ -396,13 +453,13 @@ + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="133"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="132"/> + <source>Swap</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="138"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="285"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="137"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="297"/> + <source>Not enabled</source> + <translation type="unfinished"></translation> + </message> +@@ -410,109 +467,109 @@ + <context> + <name>NetDetailsModel</name> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="138"/> +- <location filename="../sysresource/netdetailsmodel.cpp" line="140"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="151"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="153"/> + <source>IPv4</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="151"/> +- <location filename="../sysresource/netdetailsmodel.cpp" line="153"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="164"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="166"/> + <source>IPv6</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="161"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="174"/> + <source>Connection type</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="168"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="181"/> + <source>ESSID</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="173"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="186"/> + <source>Link quality</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="178"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="191"/> + <source>Signal strength</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="183"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="196"/> + <source>Noise level</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="189"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="202"/> + <source>MAC</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="194"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="207"/> + <source>Bandwidth</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="199"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="212"/> + <source>RX packets</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="204"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="217"/> + <source>RX bytes</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="209"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="222"/> + <source>RX errors</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="214"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="227"/> + <source>RX dropped</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="219"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="232"/> + <source>RX overruns</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="224"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="237"/> + <source>RX frame</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="229"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="242"/> + <source>TX packets</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="234"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="247"/> + <source>TX bytes</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="239"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="252"/> + <source>TX errors</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="244"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="257"/> + <source>TX dropped</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="249"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="262"/> + <source>TX overruns</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/netdetailsmodel.cpp" line="254"/> ++ <location filename="../sysresource/netdetailsmodel.cpp" line="267"/> + <source>TX carrier</source> + <translation type="unfinished"></translation> + </message> +@@ -538,7 +595,7 @@ + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/nethistorywidget.cpp" line="157"/> ++ <location filename="../sysresource/nethistorywidget.cpp" line="156"/> + <source>Receive</source> + <translation type="unfinished"></translation> + </message> +@@ -572,6 +629,21 @@ + <translation type="unfinished"></translation> + </message> + </context> ++<context> ++ <name>NetItemWidget</name> ++ <message> ++ <location filename="../sysresource/netitemwidget.cpp" line="62"/> ++ <location filename="../sysresource/netitemwidget.cpp" line="80"/> ++ <source>Receive</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../sysresource/netitemwidget.cpp" line="67"/> ++ <location filename="../sysresource/netitemwidget.cpp" line="85"/> ++ <source>Send</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -641,114 +713,114 @@ + <context> + <name>ProcessTableView</name> + <message> +- <location filename="../process/processtableview.cpp" line="215"/> ++ <location filename="../process/processtableview.cpp" line="218"/> + <source>No search result</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="590"/> +- <location filename="../process/processtableview.cpp" line="594"/> ++ <location filename="../process/processtableview.cpp" line="593"/> ++ <location filename="../process/processtableview.cpp" line="597"/> + <source>Stop process</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="305"/> +- <location filename="../process/processtableview.cpp" line="644"/> ++ <location filename="../process/processtableview.cpp" line="308"/> + <location filename="../process/processtableview.cpp" line="647"/> +- <location filename="../process/processtableview.cpp" line="739"/> ++ <location filename="../process/processtableview.cpp" line="650"/> ++ <location filename="../process/processtableview.cpp" line="748"/> + <source>End process</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="307"/> +- <location filename="../process/processtableview.cpp" line="684"/> ++ <location filename="../process/processtableview.cpp" line="310"/> + <location filename="../process/processtableview.cpp" line="687"/> +- <location filename="../process/processtableview.cpp" line="769"/> ++ <location filename="../process/processtableview.cpp" line="690"/> ++ <location filename="../process/processtableview.cpp" line="778"/> + <source>Kill process</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="321"/> ++ <location filename="../process/processtableview.cpp" line="324"/> + <source>Very High</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="322"/> ++ <location filename="../process/processtableview.cpp" line="325"/> + <source>High</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="323"/> ++ <location filename="../process/processtableview.cpp" line="326"/> + <source>Normal</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="324"/> ++ <location filename="../process/processtableview.cpp" line="327"/> + <source>Low</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="325"/> ++ <location filename="../process/processtableview.cpp" line="328"/> + <source>Very Low</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="326"/> ++ <location filename="../process/processtableview.cpp" line="329"/> + <source>Custom</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="331"/> ++ <location filename="../process/processtableview.cpp" line="334"/> + <source>Change Priority</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="333"/> ++ <location filename="../process/processtableview.cpp" line="336"/> + <source>Properties</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="351"/> ++ <location filename="../process/processtableview.cpp" line="354"/> + <source>User</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="357"/> ++ <location filename="../process/processtableview.cpp" line="360"/> + <source>Disk</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="363"/> ++ <location filename="../process/processtableview.cpp" line="366"/> + <source>CPU</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="369"/> ++ <location filename="../process/processtableview.cpp" line="372"/> + <source>ID</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="375"/> ++ <location filename="../process/processtableview.cpp" line="378"/> + <source>Flownet Persec</source> + <translation type="unfinished">Netflow</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="381"/> ++ <location filename="../process/processtableview.cpp" line="384"/> + <source>Memory</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="387"/> ++ <location filename="../process/processtableview.cpp" line="390"/> + <source>Priority</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="735"/> ++ <location filename="../process/processtableview.cpp" line="744"/> + <source>End the selected process %1 (PID %2) ?</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="765"/> ++ <location filename="../process/processtableview.cpp" line="774"/> + <source>Kill the selected process %1 (PID %2) ?</source> + <translation type="unfinished"></translation> + </message> +@@ -757,14 +829,14 @@ + <translation type="obsolete">End the selected process "%1"(PID:%2)?</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="736"/> ++ <location filename="../process/processtableview.cpp" line="745"/> + <source>Ending a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be ended. + Are you sure to continue?</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="740"/> +- <location filename="../process/processtableview.cpp" line="770"/> ++ <location filename="../process/processtableview.cpp" line="749"/> ++ <location filename="../process/processtableview.cpp" line="779"/> + <source>Cancel</source> + <translation type="unfinished"></translation> + </message> +@@ -773,18 +845,18 @@ Are you sure to continue?</source> + <translation type="obsolete">Kill the selected process "%1"(PID:%2)?</translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="766"/> ++ <location filename="../process/processtableview.cpp" line="775"/> + <source>Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed. + Are you sure to continue?</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="782"/> ++ <location filename="../process/processtableview.cpp" line="791"/> + <source>Not allowed operation!</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processtableview.cpp" line="783"/> ++ <location filename="../process/processtableview.cpp" line="792"/> + <source>OK</source> + <translation type="unfinished"></translation> + </message> +@@ -810,6 +882,7 @@ Are you sure to continue?</source> + <context> + <name>QObject</name> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="433"/> + <location filename="../sysresource/memhistorywidget.cpp" line="35"/> + <location filename="../sysresource/nethistorywidget.cpp" line="36"/> + <source>KiB</source> +@@ -817,39 +890,46 @@ Are you sure to continue?</source> + </message> + <message> + <location filename="../process/processtablemodel.cpp" line="57"/> ++ <location filename="../sysresource/commoninfo.cpp" line="440"/> + <location filename="../sysresource/memhistorywidget.cpp" line="39"/> + <location filename="../sysresource/nethistorywidget.cpp" line="43"/> + <source>MiB</source> + <translation>MB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="447"/> + <location filename="../sysresource/memhistorywidget.cpp" line="43"/> + <location filename="../sysresource/nethistorywidget.cpp" line="50"/> + <source>GiB</source> + <translation>GB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="454"/> + <location filename="../sysresource/memhistorywidget.cpp" line="47"/> + <location filename="../sysresource/nethistorywidget.cpp" line="57"/> + <source>TiB</source> + <translation>TB</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="435"/> + <location filename="../sysresource/nethistorywidget.cpp" line="38"/> + <source>KiB/s</source> + <translation>KB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="442"/> + <location filename="../sysresource/nethistorywidget.cpp" line="45"/> + <source>MiB/s</source> + <translation>MB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="449"/> + <location filename="../sysresource/nethistorywidget.cpp" line="52"/> + <source>GiB/s</source> + <translation>GB/s</translation> + </message> + <message> ++ <location filename="../sysresource/commoninfo.cpp" line="456"/> + <location filename="../sysresource/nethistorywidget.cpp" line="59"/> + <source>TiB/s</source> + <translation>TB/s</translation> +@@ -969,31 +1049,28 @@ Are you sure to continue?</source> + <context> + <name>ReniceDialog</name> + <message> +- <location filename="../dialog/renicedialog.cpp" line="68"/> +- <location filename="../dialog/renicedialog.cpp" line="300"/> ++ <location filename="../dialog/renicedialog.cpp" line="57"/> + <source>Change Priority of Process %1 (PID: %2)</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="86"/> +- <location filename="../dialog/renicedialog.cpp" line="330"/> ++ <location filename="../dialog/renicedialog.cpp" line="61"/> ++ <location filename="../dialog/renicedialog.cpp" line="242"/> + <source>Nice value:</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="107"/> ++ <location filename="../dialog/renicedialog.cpp" line="80"/> + <source>Note:The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority.</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="119"/> +- <location filename="../dialog/renicedialog.cpp" line="310"/> ++ <location filename="../dialog/renicedialog.cpp" line="91"/> + <source>Cancel</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../dialog/renicedialog.cpp" line="124"/> +- <location filename="../dialog/renicedialog.cpp" line="320"/> ++ <location filename="../dialog/renicedialog.cpp" line="96"/> + <source>Change Priority</source> + <translation type="unfinished"></translation> + </message> +diff --git a/src/translation/ukui-system-monitor_kk.ts b/src/translation/ukui-system-monitor_kk.ts +index 767c397..3afa9d4 100644 +--- a/src/translation/ukui-system-monitor_kk.ts ++++ b/src/translation/ukui-system-monitor_kk.ts +@@ -66,7 +66,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>قۇبىلداۋ</translation> ++ <translation>قابىلداۋ ەتۋ</translation> + </message> + <message> + <source>Send</source> +@@ -310,19 +310,19 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>L1i cache</source> +- <translation>L 1 i باسەڭدەتكىشتىق ساقتاعىش</translation> ++ <translation>L1 تەجەۋ ساقتاعىش</translation> + </message> + <message> + <source>L1d cache</source> +- <translation>L1d باسەڭدەتكىشتىق ساقتاعىش</translation> ++ <translation>L1 تەجەۋ ساقتاعىش</translation> + </message> + <message> + <source>L2 cache</source> +- <translation>L2 باسەڭدەتكىشتىق ساقتاعىش</translation> ++ <translation>L2 تەجەۋ ساقتاعىش</translation> + </message> + <message> + <source>L3 cache</source> +- <translation>L3 باسەڭدەتكىشتىق ساقتاعىش</translation> ++ <translation>L3 تەجەۋ ساقتاعىش</translation> + </message> + <message> + <source>Load average</source> +@@ -346,7 +346,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>OS type</source> +- <translation>OS تيپى</translation> ++ <translation>تيپى</translation> + </message> + <message> + <source>Version</source> +@@ -361,7 +361,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>CPU</source> +- <translation>ورتالىعى بٸرجاقتٸلٸ ەتۋ قىلعىش</translation> ++ <translation>ورتالىعى بٸر جاق قىلعىش</translation> + </message> + </context> + <context> +@@ -372,7 +372,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>CPU</source> +- <translation>ورتالىعى بٸرجاقتٸلٸ ەتۋ قىلعىش</translation> ++ <translation>ورتالىعى بٸر جاق قىلعىش</translation> + </message> + </context> + <context> +@@ -889,7 +889,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + <name>KChartView</name> + <message> + <source>60 seconds</source> +- <translation>60 سەكنوت</translation> ++ <translation>60 سەكونت</translation> + </message> + </context> + <context> +@@ -908,7 +908,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دەسكالار</translation> + </message> + </context> + <context> +@@ -923,7 +923,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>About</source> +- <translation>جونٸندە</translation> ++ <translation>جايىندا</translation> + </message> + <message> + <source>Exit</source> +@@ -935,11 +935,11 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Option</source> +- <translation>تالداۋ</translation> ++ <translation>تالدانبا</translation> + </message> + <message> + <source>Minimize</source> +- <translation>ەڭ كشكەنە بەينە</translation> ++ <translation>كىشرەيتۋ</translation> + </message> + <message> + <source>Maximize</source> +@@ -947,7 +947,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Close</source> +- <translation>تاقاۋ</translation> ++ <translation>جابۋ</translation> + </message> + <message> + <source>Restore</source> +@@ -1353,7 +1353,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دەسكالار</translation> + </message> + <message> + <source>Cpu Details</source> +@@ -1384,7 +1384,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached</source> +- <translation>باسەڭدەتكىشتىق ساقتاعىش</translation> ++ <translation>تەجەۋ ساقتاعىش</translation> + </message> + <message> + <source>Buffers</source> +@@ -1392,7 +1392,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached swap</source> +- <translation>باسەڭدەتكىشتىق ساقتاعىش سايكەستىرۋ</translation> ++ <translation>تەجەۋ ساقتاعىش سايكەستىرۋ</translation> + </message> + <message> + <source>Active</source> +@@ -1412,7 +1412,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Total swap</source> +- <translation>جالپى ئالماشتۇرۇلغىنى</translation> ++ <translation>جالپٸ ئالماشتۇرۇلغىنى</translation> + </message> + <message> + <source>Free swap</source> +@@ -1687,7 +1687,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>MAC</source> +- <translation>MAC ٵدىرىسى</translation> ++ <translation>MAC</translation> + </message> + <message> + <source>Bandwidth</source> +@@ -1695,51 +1695,51 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>RX packets</source> +- <translation>RX ساندىق مالىمەت بوقشاسٸ</translation> ++ <translation>ساندىق مالىمەت بوقشاسٸ</translation> + </message> + <message> + <source>RX bytes</source> +- <translation>RX بايت</translation> ++ <translation>بايت</translation> + </message> + <message> + <source>RX errors</source> +- <translation>RX قاتەلىگى</translation> ++ <translation>قاتەلىگى</translation> + </message> + <message> + <source>RX dropped</source> +- <translation>RX تاستالىپ ەتتى</translation> ++ <translation>تاستالىپ ەتتى</translation> + </message> + <message> + <source>RX overruns</source> +- <translation>RX شەكتەن ٸشٸپ كەتتى</translation> ++ <translation>شەكتەن ٸشٸپ كەتتى</translation> + </message> + <message> + <source>RX frame</source> +- <translation>RX كانادانىڭ</translation> ++ <translation>كانادانىڭ</translation> + </message> + <message> + <source>TX packets</source> +- <translation>TX ساندىق مالىمەت بوقشاسٸ</translation> ++ <translation>ساندىق مالىمەت بوقشاسٸ</translation> + </message> + <message> + <source>TX bytes</source> +- <translation>TX بايت</translation> ++ <translation>بايت</translation> + </message> + <message> + <source>TX errors</source> +- <translation>TX قاتەلىگى</translation> ++ <translation>قاتەلىگى</translation> + </message> + <message> + <source>TX dropped</source> +- <translation>TX ٷزٸلٸپ كەتتى</translation> ++ <translation>ٷزٸلٸپ كەتتى</translation> + </message> + <message> + <source>TX overruns</source> +- <translation>TX شەكتەن ٸشٸپ كەتتى</translation> ++ <translation>شەكتەن ٸشٸپ كەتتى</translation> + </message> + <message> + <source>TX carrier</source> +- <translation>TX تاسۋشى تولقىن</translation> ++ <translation>تاسۋشى تولقىن</translation> + </message> + </context> + <context> +@@ -1761,7 +1761,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Receive</source> +- <translation>قۇبىلداۋ</translation> ++ <translation>قابىلداۋ ەتۋ</translation> + </message> + </context> + <context> +@@ -1776,7 +1776,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Broadcast:</source> +- <translation>راديو:</translation> ++ <translation>رادىيو:</translation> + </message> + <message> + <source>Prefixlen:</source> +@@ -2140,7 +2140,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>User</source> +- <translation>الارمان مى</translation> ++ <translation>پايدالانۋشٸ</translation> + </message> + <message> + <source>Disk</source> +@@ -2148,7 +2148,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU</source> +- <translation>ورتالىعى بٸرجاقتٸلٸ ەتۋ قىلعىش</translation> ++ <translation>ورتالىعى بٸر جاق قىلعىش</translation> + </message> + <message> + <source>ID</source> +@@ -2156,7 +2156,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Flownet Persec</source> +- <translation>Flownet Persec</translation> ++ <translation>ﻡەﺮﻛﻯﺯﻰﻳ ﺏﻯﺭ ﺕەﺭەﭖ ﻕﻰﻠﻏۇﭺ</translation> + </message> + <message> + <source>Memory</source> +@@ -2164,7 +2164,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Priority</source> +- <translation>تۇراقتى</translation> ++ <translation>الدىن ويلاسۋ دارەجەسى</translation> + </message> + </context> + <context> +@@ -2223,7 +2223,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>User</source> +- <translation>الارمان مى</translation> ++ <translation>پايدالانۋشٸ</translation> + </message> + <message> + <source>Disk</source> +@@ -2231,7 +2231,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU</source> +- <translation>ورتالىعى بٸرجاقتٸلٸ ەتۋ قىلعىش</translation> ++ <translation>ورتالىعى بٸر جاق قىلعىش</translation> + </message> + <message> + <source>ID</source> +@@ -2239,7 +2239,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Flownet Persec</source> +- <translation>Flownet Persec</translation> ++ <translation>ﻡەﺮﻛﻯﺯﻰﻳ ﺏﻯﺭ ﺕەﺭەﭖ ﻕﻰﻠﻏۇﭺ</translation> + </message> + <message> + <source>Memory</source> +@@ -2247,7 +2247,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Priority</source> +- <translation>تۇراقتى</translation> ++ <translation>الدىن ويلاسۋ دارەجەسى</translation> + </message> + <message> + <source>Ending a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be ended. +@@ -2262,7 +2262,7 @@ Are you sure to continue?</source> + <message> + <source>Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed. + Are you sure to continue?</source> +- <translation>بٸر بارٸسٸ ولتىرۋ ساندىق مالىمەتتەردى كۇيرەۋ ورىنداۋى، جيىندى بۇزۇشى ياكي حاۋىپسىزدىك خەۋپىنى ورتاعا قويۇۋېتىشى مۇمكان. تەك ئىنكاسسىز جەريانلاردىلا ٴولۋ كەرەك. ++ <translation>بٸر بارٸسٸ ولتىرۋ ساندىق مالىمەتتەردى كۇيرەۋ ورىنداۋى، جيىندى بۇزۇشى ياكي حاۋىپسىزدىك خەۋپىنى ورتاعا قويۇۋېتىشى مۇمكان. تەك ئىنكاسسىز جەريانلاردا ٴولۋ كەرەك. + ٴسىز ٴسوزسٸز داۋاملاشتۇرامٴسىز؟</translation> + </message> + <message> +@@ -2287,11 +2287,11 @@ Are you sure to continue?</source> + </message> + <message> + <source>End the selected process %1 (PID %2) ?</source> +- <translation>تالدانعان بارٸسٸنڭ %1 (PID %2) ى ئاخىرلىشامدۇ؟</translation> ++ <translation>تالدانعان بارٸسٸنڭ %1 (ازاماتتىق كۋالىك %2) ى ئاخىرلىشامدۇ؟</translation> + </message> + <message> + <source>Kill the selected process %1 (PID %2) ?</source> +- <translation>تالدانعان بارٸسٸنڭ %1 (PID %2) ى ئاخىرلاشتۇرۇلامدۇ؟</translation> ++ <translation>تالدانعان بارٸسٸنڭ %1 (ازاماتتىق كۋالىك%2) ى ئاخىرلاشتۇرالامدۇ؟</translation> + </message> + </context> + <context> +@@ -2302,7 +2302,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Applications</source> +- <translation>قولدانعىش پٸروگٸراممالار</translation> ++ <translation>قولدانعىش پىروگراممىلار</translation> + </message> + <message> + <source>My Processes</source> +@@ -3020,7 +3020,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU Time:</source> +- <translation>CPU ۋاقىتى:</translation> ++ <translation>ۋاقىتى:</translation> + </message> + <message> + <source>Started Time:</source> +@@ -3051,11 +3051,11 @@ Are you sure to continue?</source> + </message> + <message> + <source>Change Priority of Process %1 (PID: %2)</source> +- <translation>٪1 بارٸسٸنڭ ماڭىزدىلىعىن وزگەرتۋ (PID: ٪2)</translation> ++ <translation>%1 بارٸسٸنڭ ماڭىزدىلىعىن وزگەرتۋ (وڭ %2)</translation> + </message> + <message> + <source>Note:The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority.</source> +- <translation type="unfinished"></translation> ++ <translation>ەسكەرتپەۋ:بٸر بارٸسٸنڭ ماڭىزدىلىعىن ونىڭ جاعىمدى مانى مەنەن اتا ىستەيدى. بٸر دەيىن تومەن بولعان جاعىمدى ٴمان بٸر دەيىن جوعارعى ماڭىزدى ورٸنعا بۇرشاق كەلدى.</translation> + </message> + </context> + <context> +@@ -3134,7 +3134,7 @@ Are you sure to continue?</source> + <name>ServiceTableModel</name> + <message> + <source>Name</source> +- <translation>گرۋپپا مى</translation> ++ <translation>ات-فاميليا</translation> + </message> + <message> + <source>LoadState</source> +@@ -3150,15 +3150,15 @@ Are you sure to continue?</source> + </message> + <message> + <source>State</source> +- <translation>ش ول ا ر</translation> ++ <translation>كۇيى</translation> + </message> + <message> + <source>Description</source> +- <translation>تۇسىندىرۋ</translation> ++ <translation>تاكتيكا تۇسٸندٸرۋشٸ</translation> + </message> + <message> + <source>PID</source> +- <translation>PID</translation> ++ <translation>ازاماتتىق كۋالىك</translation> + </message> + <message> + <source>StartupMode</source> +@@ -3174,7 +3174,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>بولەك</translation> + </message> + <message> + <source>stub</source> +@@ -3318,7 +3318,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>اۆتوماتىك</translation> ++ <translation>اۆتوماتتى</translation> + </message> + <message> + <source>Manual</source> +@@ -3337,7 +3337,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Start</source> +- <translation>باستال</translation> ++ <translation>باستاۋ</translation> + </message> + <message> + <source>Stop</source> +@@ -3353,7 +3353,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>اۆتوماتىك</translation> ++ <translation>اۆتوماتتى</translation> + </message> + <message> + <source>Manual</source> +@@ -3373,23 +3373,23 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>بولەك</translation> + </message> + <message> + <source>State</source> +- <translation>ش ول ا ر</translation> ++ <translation>كۇيى</translation> + </message> + <message> + <source>Startup Type</source> +- <translation>باستال تورى تۇرى</translation> ++ <translation>باستال تۇرى</translation> + </message> + <message> + <source>Description</source> +- <translation>تۇسىندىرۋ</translation> ++ <translation>تاكتيكا تۇسٸندٸرۋشٸ</translation> + </message> + <message> + <source>PID</source> +- <translation>PID</translation> ++ <translation>ازاماتتىق كۋالىك</translation> + </message> + <message> + <source>stub</source> +@@ -3745,7 +3745,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>NET: </source> +- <translation>NET بايلانىس تورى: </translation> ++ <translation>بايلانىس تورى: </translation> + </message> + <message> + <source>CPU: </source> +@@ -3753,7 +3753,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>RAM: </source> +- <translation>RAM ٸشكٸ ساقتاعىش: </translation> ++ <translation>ٸشكٸ ساقتاعىش: </translation> + </message> + <message> + <source>Disk: </source> +@@ -3772,7 +3772,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>System monitor is a desktop application that face desktop users of Kylin operating system,It meets the needs of users to monitor the system process, system resources and file system</source> +- <translation>سەستيما كۇزەتۋشى بولسا Kylin جوبالاۋ سەستاماسىنداعى ۇستەل بەتى ٸستەتۋشٸلەرگە بەتتەلگەن ۇستەلئۈستى پٸروگٸرامماسٸ بولىپ، ول ٸستەتۋشٸلەردٸڭ سەستيما جاعٸ، سەستيما بايلٸعٸ ۋا حۇجات سەستاماسىن كۇزەتۋگە سۇرانٸسٸن قاندىرادى.</translation> ++ <translation>سەستيما كۇزەتۋشى بولسا Kylin جوبالاۋ سەستاماسىنداعى ۇستەل بەتى ٸستەتۋشٸلەرگە بەتتەلگەن ۇستەلئۈستى پىروگىرامماسى بولىپ، ول ٸستەتۋشٸلەردٸڭ سەستيما جاعٸ، سەستيما بايلٸعٸ ۋا حۇجات سەستاماسىن كۇزەتۋگە سۇرانٸسٸن قاندىرادى.</translation> + </message> + <message> + <source>Service and support team:</source> +diff --git a/src/translation/ukui-system-monitor_ky.ts b/src/translation/ukui-system-monitor_ky.ts +index dd17167..093fae5 100644 +--- a/src/translation/ukui-system-monitor_ky.ts ++++ b/src/translation/ukui-system-monitor_ky.ts +@@ -66,7 +66,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>قابىلداش</translation> ++ <translation>قابىلدوو جاسوو ،اتقارۇۇ</translation> + </message> + <message> + <source>Send</source> +@@ -310,19 +310,19 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>L1i cache</source> +- <translation>L 1 i بۇفېرلىق ساقتاعىچ</translation> ++ <translation>L1 بۇففىردىك ساقتاعىچ</translation> + </message> + <message> + <source>L1d cache</source> +- <translation>L1d بۇفېرلىق ساقتاعىچ</translation> ++ <translation>L1 بۇففىردىك ساقتاعىچ</translation> + </message> + <message> + <source>L2 cache</source> +- <translation>L2 بۇفېرلىق ساقتاعىچ</translation> ++ <translation>L2 بۇففىردىك ساقتاعىچ</translation> + </message> + <message> + <source>L3 cache</source> +- <translation>L3 بۇفېرلىق ساقتاعىچ</translation> ++ <translation>L3 بۇففىردىك ساقتاعىچ</translation> + </message> + <message> + <source>Load average</source> +@@ -346,7 +346,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>OS type</source> +- <translation>OS تۉرۉ</translation> ++ <translation>تۉرۉ</translation> + </message> + <message> + <source>Version</source> +@@ -361,7 +361,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>CPU</source> +- <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> ++ <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> + </message> + </context> + <context> +@@ -372,7 +372,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>CPU</source> +- <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> ++ <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> + </message> + </context> + <context> +@@ -908,7 +908,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دەيلەر</translation> + </message> + </context> + <context> +@@ -935,11 +935,11 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Option</source> +- <translation>تانداش</translation> ++ <translation>تاندالما</translation> + </message> + <message> + <source>Minimize</source> +- <translation>ەڭ كىچىك ابالى</translation> ++ <translation>كىچىرەيتۉۉ</translation> + </message> + <message> + <source>Maximize</source> +@@ -947,7 +947,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Close</source> +- <translation>بەكىتىش</translation> ++ <translation>جابۇۇ</translation> + </message> + <message> + <source>Restore</source> +@@ -1353,7 +1353,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دەيلەر</translation> + </message> + <message> + <source>Cpu Details</source> +@@ -1384,7 +1384,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached</source> +- <translation>بۇفېرلىق ساقتاعىچ</translation> ++ <translation>بۇففىردىك ساقتاعىچ</translation> + </message> + <message> + <source>Buffers</source> +@@ -1392,7 +1392,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached swap</source> +- <translation>بۇفېرلىق ساقتاعىچ الماشتىرۇۇ</translation> ++ <translation>بۇففىردىك ساقتاعىچ الماشتىرۇۇ</translation> + </message> + <message> + <source>Active</source> +@@ -1687,7 +1687,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>MAC</source> +- <translation>MAC دايىن وردۇ</translation> ++ <translation>MAC</translation> + </message> + <message> + <source>Bandwidth</source> +@@ -1695,51 +1695,51 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>RX packets</source> +- <translation>RX ساندۇۇ بايانداما بوقچوسۇ</translation> ++ <translation>ساندۇۇ بايانداما بوقچوسۇ</translation> + </message> + <message> + <source>RX bytes</source> +- <translation>RX بايت</translation> ++ <translation>بايت</translation> + </message> + <message> + <source>RX errors</source> +- <translation>RX قاتالىعى</translation> ++ <translation>قاتالىعى</translation> + </message> + <message> + <source>RX dropped</source> +- <translation>RX تاشتاپ جىبەرىلدى</translation> ++ <translation>تاشتاپ جىبەرىلدى</translation> + </message> + <message> + <source>RX overruns</source> +- <translation>RX چەكتەن اشىپ كەتتى</translation> ++ <translation>چەكتەن اشىپ كەتتى</translation> + </message> + <message> + <source>RX frame</source> +- <translation>RX كاندۇك</translation> ++ <translation>كاندۇك</translation> + </message> + <message> + <source>TX packets</source> +- <translation>TX ساندۇۇ بايانداما بوقچوسۇ</translation> ++ <translation>ساندۇۇ بايانداما بوقچوسۇ</translation> + </message> + <message> + <source>TX bytes</source> +- <translation>TX بايت</translation> ++ <translation>بايت</translation> + </message> + <message> + <source>TX errors</source> +- <translation>TX قاتالىعى</translation> ++ <translation>قاتالىعى</translation> + </message> + <message> + <source>TX dropped</source> +- <translation>TX ۉزۉلۉپ كەتتى</translation> ++ <translation>ۉزۉلۉپ كەتتى</translation> + </message> + <message> + <source>TX overruns</source> +- <translation>TX چەكتەن اشىپ كەتتى</translation> ++ <translation>چەكتەن اشىپ كەتتى</translation> + </message> + <message> + <source>TX carrier</source> +- <translation>TX تاشۇۇچۇ تولقۇن</translation> ++ <translation>تاشۇۇچۇ تولقۇن</translation> + </message> + </context> + <context> +@@ -1761,7 +1761,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Receive</source> +- <translation>قابىلداش</translation> ++ <translation>قابىلدوو جاسوو ،اتقارۇۇ</translation> + </message> + </context> + <context> +@@ -2140,7 +2140,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>User</source> +- <translation>كەرەكتۅۅچۉ ناامى</translation> ++ <translation>ىشتەتۉۉچۉ</translation> + </message> + <message> + <source>Disk</source> +@@ -2148,7 +2148,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU</source> +- <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> ++ <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> + </message> + <message> + <source>ID</source> +@@ -2156,7 +2156,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Flownet Persec</source> +- <translation>Flownet Persec</translation> ++ <translation>ﻡەﺮﻛﻯﺯﻰﻳ ﺏﻯﺭ ﺕەﺭەﭖ ﻕﻰﻠﻏۇﭺ</translation> + </message> + <message> + <source>Memory</source> +@@ -2164,7 +2164,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Priority</source> +- <translation>مۇھىمى</translation> ++ <translation>الدىن ويلوشۇش داراجاسى</translation> + </message> + </context> + <context> +@@ -2223,7 +2223,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>User</source> +- <translation>كەرەكتۅۅچۉ ناامى</translation> ++ <translation>ىشتەتۉۉچۉ</translation> + </message> + <message> + <source>Disk</source> +@@ -2231,7 +2231,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU</source> +- <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> ++ <translation>بوربورۇ بىر تاراپ جاساعىچ</translation> + </message> + <message> + <source>ID</source> +@@ -2239,7 +2239,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Flownet Persec</source> +- <translation>Flownet Persec</translation> ++ <translation>ﻡەﺮﻛﻯﺯﻰﻳ ﺏﻯﺭ ﺕەﺭەﭖ ﻕﻰﻠﻏۇﭺ</translation> + </message> + <message> + <source>Memory</source> +@@ -2247,7 +2247,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Priority</source> +- <translation>مۇھىمى</translation> ++ <translation>الدىن ويلوشۇش داراجاسى</translation> + </message> + <message> + <source>Ending a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be ended. +@@ -2262,7 +2262,7 @@ Are you sure to continue?</source> + <message> + <source>Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed. + Are you sure to continue?</source> +- <translation>بىر بارىشىن ئۆلتۈرۈش ساندۇۇ باياندامالاردى ويرون قىلۇۇ، جىيىندى بۇزۇشى كۅرۉنۉشتۅرۉ قووپسۇزدۇق خەۋپىنى وروتعو قويۇۋېتىشى مۉمكۉن. جالاڭ عانا ئىنكاسسىز جەريانلاردىلا ئۆلۈش كەرەك. ++ <translation>بىر بارىشىن ئۆلتۈرۈش ساندۇۇ باياندامالاردى ويرون قىلۇۇ، جىيىندى بۇزۇشى كۅرۉنۉشتۅرۉ قووپسۇزدۇق خەۋپىنى وروتعو قويۇۋېتىشى مۉمكۉن. جالاڭ عانا ئىنكاسسىز جەريانلاردا ئۆلۈش كەرەك. + سىز سۅزسۉز جالعاشتىراسىزبى؟</translation> + </message> + <message> +@@ -2287,11 +2287,11 @@ Are you sure to continue?</source> + </message> + <message> + <source>End the selected process %1 (PID %2) ?</source> +- <translation>تاندالعان بارىشىن %1 (PID %2) ى ئاخىرلىشامدۇ؟</translation> ++ <translation>تاندالعان بارىشىن %1 (كۉبۅلۉك %2) ى ئاخىرلىشامدۇ؟</translation> + </message> + <message> + <source>Kill the selected process %1 (PID %2) ?</source> +- <translation>تاندالعان بارىشىن %1 (PID %2) ى ئاخىرلاشتۇرۇلامدۇ؟</translation> ++ <translation>تاندالعان بارىشىن %1 (كۉبۅلۉك %2) ى ئاخىرلاشتۇرالامدۇ؟</translation> + </message> + </context> + <context> +@@ -2302,7 +2302,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Applications</source> +- <translation>قولدونۇشچان پراگراممالار</translation> ++ <translation>قولدونۇشچان پىروگراممىلار</translation> + </message> + <message> + <source>My Processes</source> +@@ -3020,7 +3020,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>CPU Time:</source> +- <translation>CPU ۇباقتى:</translation> ++ <translation>ۇباقتى:</translation> + </message> + <message> + <source>Started Time:</source> +@@ -3051,11 +3051,11 @@ Are you sure to continue?</source> + </message> + <message> + <source>Change Priority of Process %1 (PID: %2)</source> +- <translation>٪1 بارىشىن زارىلدىعىن ۅزگۅرتۉش (PID: ٪2)</translation> ++ <translation>%1 بارىشىن زارىلدىعىن ۅزگۅرتۉش (العاچى %2)</translation> + </message> + <message> + <source>Note:The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority.</source> +- <translation type="unfinished"></translation> ++ <translation>ەسكەرتۉۉ:بىر بارىشىن زارىلدىعىن انىن جاعىمدۇۇ نارقى مەنەن اتا جاسايت . بىر عاچا تۅمۅن بولعون جاعىمدۇۇ نارق بىر عاچا جوعورۇ ماڭىزدۇ ورۇنعا شاي كەلدى.</translation> + </message> + </context> + <context> +@@ -3134,7 +3134,7 @@ Are you sure to continue?</source> + <name>ServiceTableModel</name> + <message> + <source>Name</source> +- <translation>توپ ناامى</translation> ++ <translation>ات-تەك اتى</translation> + </message> + <message> + <source>LoadState</source> +@@ -3150,15 +3150,15 @@ Are you sure to continue?</source> + </message> + <message> + <source>State</source> +- <translation>ش ال ا ر</translation> ++ <translation>ابالى</translation> + </message> + <message> + <source>Description</source> +- <translation>تۉشۅندۉرۉش</translation> ++ <translation>ىقما تۉشۉندۉرۉسۉ</translation> + </message> + <message> + <source>PID</source> +- <translation>PID</translation> ++ <translation>كۉبۅلۉك</translation> + </message> + <message> + <source>StartupMode</source> +@@ -3174,7 +3174,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>بۅلۅگۉ</translation> + </message> + <message> + <source>stub</source> +@@ -3318,7 +3318,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>اپتوماتىك</translation> ++ <translation>اپتوماتتىك</translation> + </message> + <message> + <source>Manual</source> +@@ -3337,7 +3337,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Start</source> +- <translation>باشلان</translation> ++ <translation>باشتوو</translation> + </message> + <message> + <source>Stop</source> +@@ -3353,7 +3353,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>اپتوماتىك</translation> ++ <translation>اپتوماتتىك</translation> + </message> + <message> + <source>Manual</source> +@@ -3373,23 +3373,23 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>بۅلۅگۉ</translation> + </message> + <message> + <source>State</source> +- <translation>ش ال ا ر</translation> ++ <translation>ابالى</translation> + </message> + <message> + <source>Startup Type</source> +- <translation>باشلان تورۇ تۉرۉ</translation> ++ <translation>باشلان تۉرۉ</translation> + </message> + <message> + <source>Description</source> +- <translation>تۉشۅندۉرۉش</translation> ++ <translation>ىقما تۉشۉندۉرۉسۉ</translation> + </message> + <message> + <source>PID</source> +- <translation>PID</translation> ++ <translation>كۉبۅلۉك</translation> + </message> + <message> + <source>stub</source> +@@ -3745,7 +3745,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>NET: </source> +- <translation>NET بايلانىش تورۇ : </translation> ++ <translation>بايلانىش تورۇ : </translation> + </message> + <message> + <source>CPU: </source> +@@ -3753,7 +3753,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>RAM: </source> +- <translation>RAM ىچكى ساقتاعىچ : </translation> ++ <translation>ىچكى ساقتاعىچ : </translation> + </message> + <message> + <source>Disk: </source> +@@ -3772,7 +3772,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>System monitor is a desktop application that face desktop users of Kylin operating system,It meets the needs of users to monitor the system process, system resources and file system</source> +- <translation>ساامالىق كۉزۅتكۉچ بولسو Kylin ماشقۇلدانۇۇ سىستەماداقى شىرە بەتى ىشتەتۉۉچۉلۅرگۅ باعىتتالعان شىرە ئۈستى پىروگىرامماسى بولۇپ، ال ىشتەتۉۉچۉلۅردۉن ساامالىق تارتىبى ، ساامالىق بايلىعى جانا ۅجۅت سەستىمانى كۉزۅتۉۉ كەرەكتۅۅسۉن قاندىرات.</translation> ++ <translation>ساامالىق كۉزۅتكۉچ بولسو Kylin ماشقۇلدانۇۇ سىستەماداقى شىرە بەتى ىشتەتۉۉچۉلۅرگۅ باعىتتالعان شىرە ئۈستى پراگرامماسى بولۇپ، ال ىشتەتۉۉچۉلۅردۉن ساامالىق تارتىبى ، ساامالىق بايلىعى جانا ۅجۅت سەستىمانى كۉزۅتۉۉ كەرەكتۅۅسۉن قاندىرات.</translation> + </message> + <message> + <source>Service and support team:</source> +diff --git a/src/translation/ukui-system-monitor_mn.ts b/src/translation/ukui-system-monitor_mn.ts +index fa4e67d..ef23ace 100644 +--- a/src/translation/ukui-system-monitor_mn.ts ++++ b/src/translation/ukui-system-monitor_mn.ts +@@ -12,11 +12,11 @@ + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>ᠬᠦᠯᠢᠶᠡᠨ ᠠᠪᠬᠤ</translation> ++ <translation type="vanished">ᠬᠦᠯᠢᠶᠡᠨ ᠠᠪᠬᠤ</translation> + </message> + <message> + <source>Send</source> +- <translation>ᠢᠯᠡᠬᠡᠬᠦ᠌</translation> ++ <translation type="vanished">ᠢᠯᠡᠬᠡᠬᠦ᠌</translation> + </message> + </context> + <context> +@@ -127,6 +127,62 @@ + <translation>ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ</translation> + </message> + </context> ++<context> ++ <name>DiskDetailsModel</name> ++ <message> ++ <source>Model</source> ++ <translation>ᠬᠡᠯᠪᠡᠷᠢ</translation> ++ </message> ++ <message> ++ <source>Capacity</source> ++ <translation>ᠪᠠᠭᠲᠠᠭᠠᠮᠵᠢ</translation> ++ </message> ++ <message> ++ <source>Read Speed</source> ++ <translation>ᠤᠩᠰᠢᠬᠤ ᠬᠤᠷᠳᠤᠴᠠ ᠶᠢ ᠤᠩᠰᠢᠨᠠ</translation> ++ </message> ++ <message> ++ <source>Write Speed</source> ++ <translation>ᠪᠢᠴᠢᠵᠦ ᠣᠷᠣᠭᠤᠯᠤᠨᠠ</translation> ++ </message> ++ <message> ++ <source>Type</source> ++ <translation>ᠲᠦᠷᠦᠯ ᠬᠡᠯᠪᠡᠷᠢ</translation> ++ </message> ++</context> ++<context> ++ <name>DiskDetailsWidget</name> ++ <message> ++ <source>Disk</source> ++ <translation>ᠫᠠᠨᠰᠠ</translation> ++ </message> ++</context> ++<context> ++ <name>DiskHistoryWidget</name> ++ <message> ++ <source>Disk reading and writing</source> ++ <translation>ᠰᠤᠷᠢᠨᠵᠢᠨ ᠫᠠᠨᠰᠠ ᠶᠢ ᠤᠩᠰᠢᠵᠤ ᠪᠢᠴᠢᠵᠡᠢ</translation> ++ </message> ++ <message> ++ <source>Disk Read</source> ++ <translation>ᠰᠤᠷᠢᠨᠵᠢᠨ ᠫᠠᠨᠰᠠ ᠶᠢ ᠤᠩᠰᠢᠵᠤ ᠠᠪᠤᠨᠠ</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>ᠰᠤᠷᠢᠨᠵᠢᠨ ᠫᠠᠨᠰᠠ ᠶᠢ ᠪᠢᠴᠢᠵᠦ ᠣᠷᠣᠭᠤᠯᠤᠨᠠ</translation> ++ </message> ++</context> ++<context> ++ <name>DiskItemWidget</name> ++ <message> ++ <source>Disk Read</source> ++ <translation>ᠰᠤᠷᠢᠨᠵᠢᠨ ᠫᠠᠨᠰᠠ ᠶᠢ ᠤᠩᠰᠢᠵᠤ ᠠᠪᠤᠨᠠ</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>ᠰᠤᠷᠢᠨᠵᠢᠨ ᠫᠠᠨᠰᠠ ᠶᠢ ᠪᠢᠴᠢᠵᠦ ᠣᠷᠣᠭᠤᠯᠤᠨᠠ</translation> ++ </message> ++</context> + <context> + <name>FileSystemInfoItem</name> + <message> +@@ -248,6 +304,10 @@ + <source>Net Details</source> + <translation>ᠲᠣᠣᠷ ᠰᠦᠯᠵᠢᠶᠡᠨᠦ᠌ ᠨᠠᠷᠢᠨ ᠪᠠᠢᠳᠠᠯ</translation> + </message> ++ <message> ++ <source>Disk Details</source> ++ <translation>ᠫᠠᠨᠰᠠ ᠨᠠᠷᠢᠨ ᠪᠠᠢ᠌ᠳᠠᠯ</translation> ++ </message> + </context> + <context> + <name>MemDetailsModel</name> +@@ -470,6 +530,17 @@ + <translation>ᠣᠷᠣᠨ ᠄</translation> + </message> + </context> ++<context> ++ <name>NetItemWidget</name> ++ <message> ++ <source>Receive</source> ++ <translation>ᠬᠦᠯᠢᠶᠡᠨ ᠠᠪᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Send</source> ++ <translation>ᠢᠯᠡᠬᠡᠬᠦ᠌</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +diff --git a/src/translation/ukui-system-monitor_ug.ts b/src/translation/ukui-system-monitor_ug.ts +index 5fe140f..5472535 100644 +--- a/src/translation/ukui-system-monitor_ug.ts ++++ b/src/translation/ukui-system-monitor_ug.ts +@@ -66,7 +66,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>قوبۇللاش</translation> ++ <translation>قوبۇل قىلىش</translation> + </message> + <message> + <source>Send</source> +@@ -310,19 +310,19 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>L1i cache</source> +- <translation>L1 بۇفېرلىق ساقلىغۇچ</translation> ++ <translation>L1 بۇففېرلىق ساقلىغۇچ</translation> + </message> + <message> + <source>L1d cache</source> +- <translation>L1 بۇفېرلىق ساقلىغۇچ</translation> ++ <translation>L1 بۇففېرلىق ساقلىغۇچ</translation> + </message> + <message> + <source>L2 cache</source> +- <translation>L2 بۇفېرلىق ساقلىغۇچ</translation> ++ <translation>L2 بۇففېرلىق ساقلىغۇچ</translation> + </message> + <message> + <source>L3 cache</source> +- <translation>L3 بۇفېرلىق ساقلىغۇچ</translation> ++ <translation>L3 بۇففېرلىق ساقلىغۇچ</translation> + </message> + <message> + <source>Load average</source> +@@ -889,7 +889,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + <name>KChartView</name> + <message> + <source>60 seconds</source> +- <translation>60 سىكۇنت</translation> ++ <translation>60 سېكۇنت</translation> + </message> + </context> + <context> +@@ -908,7 +908,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دىسكىلار</translation> + </message> + </context> + <context> +@@ -1357,7 +1357,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Disks</source> +- <translation>دېسكىلار</translation> ++ <translation>دىسكىلار</translation> + </message> + <message> + <source>Cpu Details</source> +@@ -1388,7 +1388,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached</source> +- <translation>بۇفېرلىق ساقلىغۇچ</translation> ++ <translation>بۇففېرلىق ساقلىغۇچ</translation> + </message> + <message> + <source>Buffers</source> +@@ -1396,7 +1396,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Cached swap</source> +- <translation>بۇفېرلىق ساقلىغۇچ ئالماشتۇرۇش</translation> ++ <translation>بۇففېرلىق ساقلىغۇچ ئالماشتۇرۇش</translation> + </message> + <message> + <source>Active</source> +@@ -1416,7 +1416,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Total swap</source> +- <translation>جەمئي ئالماشتۇرۇلغىنى</translation> ++ <translation>جەمئىي ئالماشتۇرۇلغىنى</translation> + </message> + <message> + <source>Free swap</source> +@@ -1780,7 +1780,7 @@ Kylin Team <ubuntukylin-members@list.launchpad.net></source> + </message> + <message> + <source>Broadcast:</source> +- <translation>رادىئو:</translation> ++ <translation>رادىيو:</translation> + </message> + <message> + <source>Prefixlen:</source> +@@ -2266,7 +2266,7 @@ Are you sure to continue?</source> + <message> + <source>Killing a process may destroy data, break the session or introduce a security risk. Only unresponsive processes should be killed. + Are you sure to continue?</source> +- <translation>بىر جەرياننى ئۆلتۈرۈش سانلىق مەلۇماتلارنى ۋەيران قىلىشى، يىغىننى بۇزۇشى ياكى بىخەتەرلىك خەۋپىنى ئوتتۇرىغا قويۇۋېتىشى مۇمكىن. پەقەت ئىنكاسسىز جەريانلاردىلا ئۆلۈش كېرەك. ++ <translation>بىر جەرياننى ئۆلتۈرۈش سانلىق مەلۇماتلارنى ۋەيران قىلىشى، يىغىننى بۇزۇشى ياكى بىخەتەرلىك خەۋپىنى ئوتتۇرىغا قويۇۋېتىشى مۇمكىن. پەقەت ئىنكاسسىز جەريانلاردا ئۆلۈش كېرەك. + سىز چوقۇم داۋاملاشتۇرامسىز؟</translation> + </message> + <message> +@@ -2291,11 +2291,11 @@ Are you sure to continue?</source> + </message> + <message> + <source>End the selected process %1 (PID %2) ?</source> +- <translation>تاللانغان جەرياننىڭ %1 (ﻙﻰﻤﻟﻰﻛ %2) ى ئاخىرلىشامدۇ؟</translation> ++ <translation>تاللانغان جەرياننىڭ %1 (كىملىك %2) ى ئاخىرلىشامدۇ؟</translation> + </message> + <message> + <source>Kill the selected process %1 (PID %2) ?</source> +- <translation>تاللانغان جەرياننىڭ %1 (ﻙﻰﻤﻟﻰﻛ %2) ى ئاخىرلاشتۇرۇلامدۇ؟</translation> ++ <translation>تاللانغان جەرياننىڭ %1 (كىملىك%2) ى ئاخىرلاشتۇرالامدۇ؟</translation> + </message> + </context> + <context> +@@ -2306,7 +2306,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Applications</source> +- <translation>قوللىنىشچان پروگراممىلار</translation> ++ <translation>قوللىنىشچان پىروگراممىلار</translation> + </message> + <message> + <source>My Processes</source> +@@ -3055,7 +3055,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Change Priority of Process %1 (PID: %2)</source> +- <translation>%1 جەرياننىڭ مۇھىملىقىنى ئۆزگەرتىش (ﻙﻰﻤﻟﻰﻛ: %2)</translation> ++ <translation>%1 جەرياننىڭ مۇھىملىقىنى ئۆزگەرتىش (ئەسلى %2)</translation> + </message> + <message> + <source>Note:The priority of a process is given by its nice value. A lower nice value corresponds to a higher priority.</source> +@@ -3162,7 +3162,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>PID</source> +- <translation>ﻙﻰﻤﻟﻰﻛ</translation> ++ <translation>كىملىك</translation> + </message> + <message> + <source>StartupMode</source> +@@ -3178,7 +3178,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>قىسمى</translation> + </message> + <message> + <source>stub</source> +@@ -3322,7 +3322,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>ئاپتۇماتىك</translation> ++ <translation>ئاپتوماتىك</translation> + </message> + <message> + <source>Manual</source> +@@ -3357,7 +3357,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Auto</source> +- <translation>ئاپتۇماتىك</translation> ++ <translation>ئاپتوماتىك</translation> + </message> + <message> + <source>Manual</source> +@@ -3377,7 +3377,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Sub</source> +- <translation>سۇبات</translation> ++ <translation>قىسمى</translation> + </message> + <message> + <source>State</source> +@@ -3385,7 +3385,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>Startup Type</source> +- <translation>باشلان تورى تۈرى</translation> ++ <translation>باشلان تۈرى</translation> + </message> + <message> + <source>Description</source> +@@ -3393,7 +3393,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>PID</source> +- <translation>ﻙﻰﻤﻟﻰﻛ</translation> ++ <translation>كىملىك</translation> + </message> + <message> + <source>stub</source> +@@ -3776,7 +3776,7 @@ Are you sure to continue?</source> + </message> + <message> + <source>System monitor is a desktop application that face desktop users of Kylin operating system,It meets the needs of users to monitor the system process, system resources and file system</source> +- <translation>سىستېما كۆزەتكۈچ بولسا Kylin مەشغۇلات سىستېمىسىدىكى ئۈستەل يۈزى ئىشلەتكۈچىلىرىگە يۈزلەنگەن ئۈستەلئۈستى پروگراممىسى بولۇپ، ئۇ ئىشلەتكۈچىلەرنىڭ سىستېما تەرتىپى، سىستېما بايلىقى ۋە ھۆججەت سىستېمىسىنى كۆزىتىش ئېھتىياجىنى قاندۇرىدۇ.</translation> ++ <translation>سىستېما كۆزەتكۈچ بولسا Kylin مەشغۇلات سىستېمىسىدىكى ئۈستەل يۈزى ئىشلەتكۈچىلىرىگە يۈزلەنگەن ئۈستەلئۈستى پىروگراممىسى بولۇپ، ئۇ ئىشلەتكۈچىلەرنىڭ سىستېما تەرتىپى، سىستېما بايلىقى ۋە ھۆججەت سىستېمىسىنى كۆزىتىش ئېھتىياجىنى قاندۇرىدۇ.</translation> + </message> + <message> + <source>Service and support team:</source> +diff --git a/src/translation/ukui-system-monitor_zh_CN.ts b/src/translation/ukui-system-monitor_zh_CN.ts +index 41f7a91..2f2a6a6 100644 +--- a/src/translation/ukui-system-monitor_zh_CN.ts ++++ b/src/translation/ukui-system-monitor_zh_CN.ts +@@ -12,11 +12,11 @@ + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>接收</translation> ++ <translation type="vanished">接收</translation> + </message> + <message> + <source>Send</source> +- <translation>发送</translation> ++ <translation type="vanished">发送</translation> + </message> + </context> + <context> +@@ -127,6 +127,62 @@ + <translation>取消</translation> + </message> + </context> ++<context> ++ <name>DiskDetailsModel</name> ++ <message> ++ <source>Model</source> ++ <translation>型号</translation> ++ </message> ++ <message> ++ <source>Capacity</source> ++ <translation>容量</translation> ++ </message> ++ <message> ++ <source>Read Speed</source> ++ <translation>读取速度</translation> ++ </message> ++ <message> ++ <source>Write Speed</source> ++ <translation>写入速度</translation> ++ </message> ++ <message> ++ <source>Type</source> ++ <translation>类型</translation> ++ </message> ++</context> ++<context> ++ <name>DiskDetailsWidget</name> ++ <message> ++ <source>Disk</source> ++ <translation>磁盘</translation> ++ </message> ++</context> ++<context> ++ <name>DiskHistoryWidget</name> ++ <message> ++ <source>Disk reading and writing</source> ++ <translation>磁盘读写</translation> ++ </message> ++ <message> ++ <source>Disk Read</source> ++ <translation>磁盘读取</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>磁盘写入</translation> ++ </message> ++</context> ++<context> ++ <name>DiskItemWidget</name> ++ <message> ++ <source>Disk Read</source> ++ <translation>磁盘读取</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>磁盘写入</translation> ++ </message> ++</context> + <context> + <name>FileSystemInfoItem</name> + <message> +@@ -256,6 +312,10 @@ + <source>Net Details</source> + <translation>网络详情</translation> + </message> ++ <message> ++ <source>Disk Details</source> ++ <translation>磁盘详情</translation> ++ </message> + </context> + <context> + <name>MemDetailsModel</name> +@@ -478,6 +538,17 @@ + <translation>域:</translation> + </message> + </context> ++<context> ++ <name>NetItemWidget</name> ++ <message> ++ <source>Receive</source> ++ <translation>接收</translation> ++ </message> ++ <message> ++ <source>Send</source> ++ <translation>发送</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +diff --git a/src/translation/ukui-system-monitor_zh_HK.ts b/src/translation/ukui-system-monitor_zh_HK.ts +index d4899e4..510c25e 100644 +--- a/src/translation/ukui-system-monitor_zh_HK.ts ++++ b/src/translation/ukui-system-monitor_zh_HK.ts +@@ -12,11 +12,11 @@ + <name>ChartViewWidget</name> + <message> + <source>Receive</source> +- <translation>接收</translation> ++ <translation type="vanished">接收</translation> + </message> + <message> + <source>Send</source> +- <translation>發送</translation> ++ <translation type="vanished">發送</translation> + </message> + </context> + <context> +@@ -123,6 +123,62 @@ + <translation>取消</translation> + </message> + </context> ++<context> ++ <name>DiskDetailsModel</name> ++ <message> ++ <source>Model</source> ++ <translation>型號</translation> ++ </message> ++ <message> ++ <source>Capacity</source> ++ <translation>容量</translation> ++ </message> ++ <message> ++ <source>Read Speed</source> ++ <translation>讀取速度</translation> ++ </message> ++ <message> ++ <source>Write Speed</source> ++ <translation>寫入速度</translation> ++ </message> ++ <message> ++ <source>Type</source> ++ <translation>類型</translation> ++ </message> ++</context> ++<context> ++ <name>DiskDetailsWidget</name> ++ <message> ++ <source>Disk</source> ++ <translation>磁碟</translation> ++ </message> ++</context> ++<context> ++ <name>DiskHistoryWidget</name> ++ <message> ++ <source>Disk reading and writing</source> ++ <translation>磁碟讀寫</translation> ++ </message> ++ <message> ++ <source>Disk Read</source> ++ <translation>磁碟讀取</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>磁碟寫入</translation> ++ </message> ++</context> ++<context> ++ <name>DiskItemWidget</name> ++ <message> ++ <source>Disk Read</source> ++ <translation>磁碟讀取</translation> ++ </message> ++ <message> ++ <source>Disk Write</source> ++ <translation>磁碟寫入</translation> ++ </message> ++</context> + <context> + <name>FileSystemInfoItem</name> + <message> +@@ -248,6 +304,10 @@ + <source>Net Details</source> + <translation>網路詳情</translation> + </message> ++ <message> ++ <source>Disk Details</source> ++ <translation>磁碟詳情</translation> ++ </message> + </context> + <context> + <name>MemDetailsModel</name> +@@ -470,6 +530,17 @@ + <translation>域:</translation> + </message> + </context> ++<context> ++ <name>NetItemWidget</name> ++ <message> ++ <source>Receive</source> ++ <translation>接收</translation> ++ </message> ++ <message> ++ <source>Send</source> ++ <translation>發送</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/0036-54-nile.patch ukui-system-monitor-4.20.0.0/debian/patches/0036-54-nile.patch --- ukui-system-monitor-4.10.0.0/debian/patches/0036-54-nile.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/0036-54-nile.patch 2024-11-19 17:11:36.000000000 +0800 @@ -0,0 +1,9693 @@ +From: nil <zhoubin@kylinos.cn> +Date: Tue, 18 Feb 2025 03:36:58 +0000 +Subject: =?utf-8?b?ITU0IOWQjOatpW5pbGXliIbmlK/ku6PnoIEgTWVyZ2UgcHVsbCByZXF1?= + =?utf-8?b?ZXN0ICE1NCBmcm9tIOS9leaAneiDnC9vcGVua3lsaW4vaHVhbmdoZQ==?= + +--- + src/controls/kgroupbutton.cpp | 61 - + src/controls/kgroupbutton.h | 46 - + src/controls/mydialog.cpp | 129 +- + src/controls/mydialog.h | 16 - + src/desktopfileinfo.cpp | 85 - + src/desktopfileinfo.h | 3 - + src/dialog/procpropertiesdlg.cpp | 1 - + src/dialog/renicedialog.cpp | 1 - + src/dialog/usmaboutdialog.cpp | 270 -- + src/dialog/usmaboutdialog.h | 77 - + src/filesystem/filesystemworker.cpp | 14 - + src/filesystem/filesystemworker.h | 3 - + src/imageutil.cpp | 83 - + src/imageutil.h | 35 - + src/kleftsideitem.cpp | 238 -- + src/kleftsideitem.h | 63 - + src/kleftwidget.h | 1 - + src/krightwidget.cpp | 61 +- + src/krightwidget.h | 10 +- + src/main.cpp | 1 - + src/process/process_list.cpp | 1 - + src/process/process_oplimit.cpp | 152 - + src/process/process_oplimit.h | 54 - + src/process/processtableview.cpp | 18 +- + src/process/processtableview.h | 4 +- + src/process/processwidget.h | 1 - + src/process/processwndinfo.cpp | 36 - + src/process/processwndinfo.h | 1 - + src/service/servicemanager.cpp | 1 - + src/service/systemd1serviceinterface.cpp | 5 +- + src/src.pro | 12 - + src/util.cpp | 245 -- + src/util.h | 16 +- + src/xatom-helper.cpp | 213 - + src/xatom-helper.h | 107 - + tests/auto_test.sh | 57 + + tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp | 58 + + tests/kt-test-utils/cpp-stub-ext/stub-shadow.h | 171 + + tests/kt-test-utils/cpp-stub-ext/stubext.h | 129 + + tests/kt-test-utils/cpp-stub/addr_any.h | 298 ++ + tests/kt-test-utils/cpp-stub/addr_pri.h | 195 + + tests/kt-test-utils/cpp-stub/elfio.hpp | 4888 ++++++++++++++++++++++ + tests/kt-test-utils/cpp-stub/stub.h | 378 ++ + tests/main.cpp | 9 + + tests/tests.pro | 101 + + tests/unit_test_commoninfo.cpp | 113 + + tests/unit_test_filesystem.cpp | 118 + + tests/unit_test_process.cpp | 70 + + tests/unit_test_service.cpp | 114 + + tests/unit_test_utils.cpp | 89 + + ukui-system-monitor.pro | 7 +- + 51 files changed, 6830 insertions(+), 2029 deletions(-) + delete mode 100644 src/controls/kgroupbutton.cpp + delete mode 100644 src/controls/kgroupbutton.h + delete mode 100644 src/dialog/usmaboutdialog.cpp + delete mode 100644 src/dialog/usmaboutdialog.h + delete mode 100644 src/imageutil.cpp + delete mode 100644 src/imageutil.h + delete mode 100644 src/kleftsideitem.cpp + delete mode 100644 src/kleftsideitem.h + delete mode 100644 src/process/process_oplimit.cpp + delete mode 100644 src/process/process_oplimit.h + delete mode 100644 src/xatom-helper.cpp + delete mode 100644 src/xatom-helper.h + create mode 100755 tests/auto_test.sh + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.h + create mode 100644 tests/kt-test-utils/cpp-stub-ext/stubext.h + create mode 100644 tests/kt-test-utils/cpp-stub/addr_any.h + create mode 100644 tests/kt-test-utils/cpp-stub/addr_pri.h + create mode 100644 tests/kt-test-utils/cpp-stub/elfio.hpp + create mode 100644 tests/kt-test-utils/cpp-stub/stub.h + create mode 100644 tests/main.cpp + create mode 100644 tests/tests.pro + create mode 100644 tests/unit_test_commoninfo.cpp + create mode 100644 tests/unit_test_filesystem.cpp + create mode 100644 tests/unit_test_process.cpp + create mode 100644 tests/unit_test_service.cpp + create mode 100644 tests/unit_test_utils.cpp + +diff --git a/src/controls/kgroupbutton.cpp b/src/controls/kgroupbutton.cpp +deleted file mode 100644 +index 4064eee..0000000 +--- a/src/controls/kgroupbutton.cpp ++++ /dev/null +@@ -1,61 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#include "kgroupbutton.h" +- +-#include <QStylePainter> +-#include <QDebug> +-#include <QStyle> +- +-KGroupButton::KGroupButton(QWidget *parent) +- : QPushButton(parent) +-{ +- mPosition = GroupButtonStyleOption::OnlyOne; +- this->setProperty("useButtonPalette", true); +- connect(this,&KGroupButton::toggled,this,[=](bool isChecked){ +- if (isChecked) { +- this->setProperty("useButtonPalette", false); +- } else { +- this->setProperty("useButtonPalette", true); +- } +- }); +-} +- +-KGroupButton::KGroupButton(const QString &text, QWidget *parent) +- : QPushButton(text, parent) +-{ +- mPosition = GroupButtonStyleOption::OnlyOne; +-} +- +-KGroupButton::KGroupButton(const QIcon& icon, const QString &text, QWidget *parent) +- : QPushButton(icon, text, parent) +-{ +- mPosition = GroupButtonStyleOption::OnlyOne; +-} +- +-void KGroupButton::paintEvent(QPaintEvent *paintEvent) +-{ +- Q_UNUSED(paintEvent); +- QStylePainter p(this); +- GroupButtonStyleOption option; +- option.position = mPosition; +- initStyleOption(&option); +- p.drawControl(QStyle::CE_PushButton, option); +-} +diff --git a/src/controls/kgroupbutton.h b/src/controls/kgroupbutton.h +deleted file mode 100644 +index 7824f21..0000000 +--- a/src/controls/kgroupbutton.h ++++ /dev/null +@@ -1,46 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +-#ifndef KGROUPBUTTON_H +-#define KGROUPBUTTON_H +- +-#include "../style/usmproxystyle.h" +-#include <QPushButton> +- +-class KGroupButton : public QPushButton +-{ +- Q_OBJECT +-public: +- explicit KGroupButton(QWidget *parent = nullptr); +- explicit KGroupButton(const QString &text, QWidget *parent = nullptr); +- KGroupButton(const QIcon& icon, const QString &text, QWidget *parent = nullptr); +- +- inline GroupButtonStyleOption::ButtonPosition position() +- { return mPosition; } +- inline void setPosition(GroupButtonStyleOption::ButtonPosition pos) +- { mPosition = pos; } +- +-protected: +- void paintEvent(QPaintEvent *) override; +- +-private: +- GroupButtonStyleOption::ButtonPosition mPosition; +-}; +- +-#endif // KGROUPBUTTON_H +diff --git a/src/controls/mydialog.cpp b/src/controls/mydialog.cpp +index 4a36aca..4be0bd0 100644 +--- a/src/controls/mydialog.cpp ++++ b/src/controls/mydialog.cpp +@@ -19,7 +19,6 @@ + */ + + #include "mydialog.h" +-#include "../xatom-helper.h" + #include "../macro.h" + #include "../util.h" + +@@ -37,18 +36,8 @@ + + MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent, SIZE_MODEL sizeModel) : + QDialog(parent) +- , m_titleWidth(0) + , mousePressed(false) + { +- QString platform = QGuiApplication::platformName(); +- if (!platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive)) { +- MotifWmHints hints; +- hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; +- hints.functions = MWM_FUNC_ALL; +- hints.decorations = MWM_DECOR_BORDER; +- XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); +- } +- //this->setWindowFlags(this->windowFlags() | Qt::Tool | Qt::WindowCloseButtonHint); + m_sizeModel = sizeModel; + + this->setAttribute(Qt::WA_TranslucentBackground); +@@ -64,30 +53,12 @@ MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent + break; + } + +- const QByteArray id(THEME_QT_SCHEMA); +- if(QGSettings::isSchemaInstalled(id)) +- { +- styleSettings = new QGSettings(id); +- } +- +- initThemeStyle(); +- +- m_titleIcon = new QLabel; +- m_titleIcon->setPixmap(QIcon::fromTheme("ukui-system-monitor").pixmap(24,24)); +- m_titleIcon->setFixedWidth(24); +- +- QHBoxLayout* titleLayout = new QHBoxLayout(); +- titleLayout->setContentsMargins(8, 4, 4, 0); +- titleLayout->setSpacing(8); ++ this->setWindowIcon(QIcon::fromTheme("ukui-system-monitor")); ++ this->setWindowTitle(title); + + m_topLayout = new QHBoxLayout; + m_topLayout->setContentsMargins(24, 0, 24, 0); + +- m_titleLabel = new QLabel; +- m_titleLabel->hide(); +- titleLayout->addWidget(m_titleIcon, 0, Qt::AlignLeft|Qt::AlignTop); +- titleLayout->addWidget(m_titleLabel, 0, Qt::AlignLeft|Qt::AlignTop); +- + m_messageLabel = new QLabel; + m_messageLabel->hide(); + m_messageLabel->setAttribute(Qt::WA_TransparentForMouseEvents); +@@ -106,20 +77,6 @@ MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent + + m_topLayout->addLayout(textLayout); + +- closeButton = new QPushButton(); +- closeButton->setObjectName("CloseButton"); +- closeButton->setFlat(true); +- connect(closeButton,&QPushButton::clicked,this,[=](){ +- this->deleteLater(); +- this->close(); +- }); +- closeButton->setIcon(QIcon::fromTheme("window-close-symbolic")); +- closeButton->setAttribute(Qt::WA_NoMousePropagation); +- closeButton->setProperty("isWindowButton", 0x2); +- closeButton->setProperty("useIconHighlightEffect", 0x8); +- closeButton->setFixedSize(30, 30); +- titleLayout->addWidget(closeButton, 0, Qt::AlignTop | Qt::AlignRight); +- + m_contentLayout = new QVBoxLayout(); + m_contentLayout->setContentsMargins(24,0,24,0); + m_contentLayout->setSpacing(0); +@@ -139,8 +96,6 @@ MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(4); + +- mainLayout->addLayout(titleLayout); +- mainLayout->addStretch(1); + mainLayout->addLayout(m_topLayout); + mainLayout->addStretch(1); + mainLayout->addLayout(m_contentLayout); +@@ -157,12 +112,7 @@ MyDialog::MyDialog(const QString &title, const QString &message, QWidget *parent + this->setFocusPolicy(Qt::ClickFocus); + this->setFocus(); + +- setTitle(title); + setMessage(message); +- //this->moveToCenter(); +- this->m_titleLabel->setFixedWidth(this->width()-this->m_titleIcon->width()-this->closeButton->width()-20); +- this->m_titleWidth = this->m_titleLabel->width(); +- onThemeFontChange(fontSize); + } + + MyDialog::~MyDialog() +@@ -185,54 +135,6 @@ MyDialog::~MyDialog() + // item->widget()->deleteLater(); + // delete item; + // } +- if (styleSettings) { +- delete styleSettings; +- styleSettings = nullptr; +- } +-} +- +-void MyDialog::initThemeStyle() +-{ +- if (!styleSettings) { +- fontSize = DEFAULT_FONT_SIZE; +- return; +- } +- connect(styleSettings,&QGSettings::changed,[=](QString key) +- { +- if ("systemFont" == key || "systemFontSize" == key) { +- fontSize = styleSettings->get(FONT_SIZE).toString().toFloat(); +- this->onThemeFontChange(fontSize); +- } else if ("iconThemeName" == key) { +- if (m_titleIcon) +- m_titleIcon->setPixmap(QIcon::fromTheme("ukui-system-monitor").pixmap(24,24)); +- } +- }); +- fontSize = styleSettings->get(FONT_SIZE).toString().toFloat(); +-} +- +-void MyDialog::onThemeFontChange(qreal lfFontSize) +-{ +- Q_UNUSED(lfFontSize); +- if (m_titleLabel && this->m_titleWidth > 0) { +- QString strTitle = getElidedText(m_titleLabel->font(), m_title, this->m_titleWidth-2); +- m_titleLabel->setText(strTitle); +- if (strTitle != m_title) { +- m_titleLabel->setToolTip(m_title); +- } else { +- m_titleLabel->setToolTip(""); +- } +- } +-} +- +-void MyDialog::updateSize() +-{ +- if (!this->testAttribute(Qt::WA_Resized)) { +- QSize size = this->sizeHint(); +- size.setWidth(qMax(size.width(), 234)); +- size.setHeight(qMax(size.height(), 196)); +- this->resize(size); +- this->setAttribute(Qt::WA_Resized, false); +- } + } + + void MyDialog::onButtonClicked() +@@ -291,16 +193,6 @@ void MyDialog::setDefaultButton(QAbstractButton *button) + this->defaultButton = button; + } + +-void MyDialog::setTitle(const QString &title) +-{ +- if (this->m_title == title) +- return; +- +- this->m_title = title; +- this->m_titleLabel->setText(title); +- this->m_titleLabel->setHidden(title.isEmpty()); +-} +- + void MyDialog::setMessage(const QString &message) + { + if (this->m_message == message) +@@ -331,16 +223,6 @@ void MyDialog::hideEvent(QHideEvent *event) + done(-1); + } + +-void MyDialog::childEvent(QChildEvent *event) +-{ +- QDialog::childEvent(event); +- if (event->added()) { +- if (this->closeButton) { +- this->closeButton->raise(); +- } +- } +-} +- + QRect MyDialog::getParentGeometry() const + { + if (this->parentWidget()) { +@@ -357,13 +239,6 @@ QRect MyDialog::getParentGeometry() const + return qApp->primaryScreen()->geometry(); + } + +-void MyDialog::moveToCenter() +-{ +- QRect qr = geometry(); +- qr.moveCenter(this->getParentGeometry().center()); +- move(qr.topLeft()); +-} +- + void MyDialog::mousePressEvent(QMouseEvent *event) + { + if (event->button() == Qt::LeftButton) { +diff --git a/src/controls/mydialog.h b/src/controls/mydialog.h +index 9c25bf7..d189e35 100644 +--- a/src/controls/mydialog.h ++++ b/src/controls/mydialog.h +@@ -25,7 +25,6 @@ + #include <QDialog> + #include <QPointer> + #include <QAbstractButton> +-#include <QGSettings> + + class QAbstractButton; + class QButtonGroup; +@@ -48,10 +47,8 @@ public: + explicit MyDialog(const QString &title, const QString& message, QWidget *parent = 0, SIZE_MODEL sizeModel = MIDDLE); + ~MyDialog(); + +- void updateSize(); + int buttonCount() const; + QRect getParentGeometry() const; +- void moveToCenter(); + + signals: + void buttonClicked(int index, const QString &text); +@@ -59,7 +56,6 @@ signals: + public slots: + int addButton(const QString &text, bool isDefault = false); + void setDefaultButton(QAbstractButton *button); +- void setTitle(const QString &title); + void setMessage(const QString& message); + void addContent(QWidget* contentWidget); + int exec() Q_DECL_OVERRIDE; +@@ -71,22 +67,14 @@ public slots: + protected: + void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; + void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE; +- void childEvent(QChildEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +-private: +- void initThemeStyle(); +- void onThemeFontChange(qreal lfFontSize); +- + private: + QLabel *m_messageLabel = nullptr; +- QLabel *m_titleLabel = nullptr; +- QLabel *m_titleIcon = nullptr; +- QPushButton *closeButton = nullptr; + QVBoxLayout *m_contentLayout = nullptr; + QHBoxLayout *m_buttonLayout = nullptr; + QHBoxLayout *m_topLayout = nullptr; +@@ -96,11 +84,7 @@ private: + QPointer<QAbstractButton> defaultButton; + int clickedButtonIndex; + +- QString m_title; +- int m_titleWidth; + QString m_message; +- qreal fontSize; +- QGSettings *styleSettings; + + QPoint dragPosition; + bool mousePressed; +diff --git a/src/desktopfileinfo.cpp b/src/desktopfileinfo.cpp +index b0942d0..d3dee89 100644 +--- a/src/desktopfileinfo.cpp ++++ b/src/desktopfileinfo.cpp +@@ -46,61 +46,6 @@ DesktopFileInfo::~DesktopFileInfo() + m_mapDesktopInfoList.clear(); + } + +-QString DesktopFileInfo::getDesktopFileNameByExec(QString strExec) +-{ +- QMap<QString, DTFileInfo>::iterator itDesktopFileInfo = m_mapDesktopInfoList.begin(); +- strExec = exchangeCustomProcMap(strExec); +- QStringList execParamList = strExec.split(QRegExp("\\s+")); +- for (; itDesktopFileInfo != m_mapDesktopInfoList.end(); itDesktopFileInfo ++) { +- if (itDesktopFileInfo.value().strExec == strExec || itDesktopFileInfo.value().strSimpleExec == strExec +- || itDesktopFileInfo.value().strExec == execParamList[0] || itDesktopFileInfo.value().strSimpleExec == execParamList[0] +- || itDesktopFileInfo.value().strStartupWMClass.toLower() == strExec.toLower() +- || itDesktopFileInfo.value().strStartupWMClass.toLower() == execParamList[0].toLower()) { +- if (itDesktopFileInfo.value().strExecParam.size() <= 1 && execParamList.size() <= 1) { +- return itDesktopFileInfo.key(); +- } else if (itDesktopFileInfo.value().strExecParam.size() > 1 +- && execParamList.size() <= itDesktopFileInfo.value().strExecParam.size()) { // 实际进程命令参数长度要比预定的相同或更短 +- bool isSameProc = true; +- for (int n = 1; n < itDesktopFileInfo.value().strExecParam.size(); n++) { +- if (!itDesktopFileInfo.value().strExecParam[n].isEmpty()) { +- if (itDesktopFileInfo.value().strExecParam[n].at(0) != '%') { // 必传参数 +- if (execParamList.size() <= n) { // 缺少必传参数,进程不匹配 +- isSameProc = false; +- break; +- } else if (execParamList[n] != itDesktopFileInfo.value().strExecParam[n]) { // 参数不必配,进程不匹配 +- isSameProc = false; +- break; +- } +- } else { +- break; +- } +- } else { +- break; +- } +- } +- if (!isSameProc) { // 实际cmd字段数少于desktop中exec的,按首字段匹配 +- if (itDesktopFileInfo.value().strExecParam[0] == execParamList[0]) { +- isSameProc = true; +- } +- } +- if (isSameProc) { +- return itDesktopFileInfo.key(); +- } +- } +- } +- } +- // 实际cmd字段数少于desktop中exec的,按首字段匹配 +- for (itDesktopFileInfo = m_mapDesktopInfoList.begin(); itDesktopFileInfo != m_mapDesktopInfoList.end(); itDesktopFileInfo ++) { +- if (itDesktopFileInfo.value().strExec == strExec || itDesktopFileInfo.value().strSimpleExec == strExec +- || itDesktopFileInfo.value().strExec == execParamList[0] || itDesktopFileInfo.value().strSimpleExec == execParamList[0] +- || itDesktopFileInfo.value().strStartupWMClass.toLower() == strExec.toLower() +- || itDesktopFileInfo.value().strStartupWMClass.toLower() == execParamList[0].toLower()) { +- return itDesktopFileInfo.key(); +- } +- } +- return ""; +-} +- + QString DesktopFileInfo::getNameByExec(QString strExec) + { + QMap<QString, DTFileInfo>::iterator itDesktopFileInfo = m_mapDesktopInfoList.begin(); +@@ -237,36 +182,6 @@ QString DesktopFileInfo::getIconByExec(QString strExec) + return ""; + } + +-QString DesktopFileInfo::getNameByDesktopFile(QString strDesktopFileName) +-{ +- QMap<QString, DTFileInfo>::iterator itDesktopFileInfo = m_mapDesktopInfoList.find(strDesktopFileName); +- if (itDesktopFileInfo != m_mapDesktopInfoList.end()) { +- if (itDesktopFileInfo.value().strName.isEmpty()) { +- if (itDesktopFileInfo.value().strGenericName.isEmpty()) { +- if (itDesktopFileInfo.value().strComment.isEmpty()) { +- return ""; +- } else { +- return itDesktopFileInfo.value().strComment; +- } +- } else { +- return itDesktopFileInfo.value().strGenericName; +- } +- } else { +- return itDesktopFileInfo.value().strName; +- } +- } +- return ""; +-} +- +-QString DesktopFileInfo::getIconByDesktopFile(QString strDesktopFileName) +-{ +- QMap<QString, DTFileInfo>::iterator itDesktopFileInfo = m_mapDesktopInfoList.find(strDesktopFileName); +- if (itDesktopFileInfo != m_mapDesktopInfoList.end()) { +- return itDesktopFileInfo.value().strIcon; +- } +- return ""; +-} +- + void DesktopFileInfo::readAllDesktopFileInfo() + { + m_mapDesktopInfoList.clear(); +diff --git a/src/desktopfileinfo.h b/src/desktopfileinfo.h +index 1088b15..2f9620e 100644 +--- a/src/desktopfileinfo.h ++++ b/src/desktopfileinfo.h +@@ -46,11 +46,8 @@ public: + + static DesktopFileInfo* instance(); + +- QString getDesktopFileNameByExec(QString strExec); + QString getNameByExec(QString strExec); + QString getIconByExec(QString strExec); +- QString getNameByDesktopFile(QString strDesktopFileName); +- QString getIconByDesktopFile(QString strDesktopFileName); + QString getAndroidAppNameByCmd(QString strCmd); + QString getAndroidAppIconByCmd(QString strCmd); + +diff --git a/src/dialog/procpropertiesdlg.cpp b/src/dialog/procpropertiesdlg.cpp +index 7648169..822160c 100644 +--- a/src/dialog/procpropertiesdlg.cpp ++++ b/src/dialog/procpropertiesdlg.cpp +@@ -22,7 +22,6 @@ + #include "../process/process_list.h" + #include "../process/process_monitor.h" + #include "../util.h" +-#include "../xatom-helper.h" + #include "../macro.h" + #include "../desktopfileinfo.h" + +diff --git a/src/dialog/renicedialog.cpp b/src/dialog/renicedialog.cpp +index 230ae85..cc423e5 100644 +--- a/src/dialog/renicedialog.cpp ++++ b/src/dialog/renicedialog.cpp +@@ -21,7 +21,6 @@ + #include "renicedialog.h" + #include "../util.h" + #include "../macro.h" +-#include "../xatom-helper.h" + + #include <QApplication> + #include <QDesktopWidget> +diff --git a/src/dialog/usmaboutdialog.cpp b/src/dialog/usmaboutdialog.cpp +deleted file mode 100644 +index 9244b0d..0000000 +--- a/src/dialog/usmaboutdialog.cpp ++++ /dev/null +@@ -1,270 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#include "usmaboutdialog.h" +-#include "../xatom-helper.h" +-#include "../macro.h" +-#include "../util.h" +- +-#include <QDesktopServices> +-#include <QPainterPath> +-#include <QPainter> +-#include <QTextDocument> +-#include <QDebug> +-#include <QAbstractTextDocumentLayout> +-#include <QTextOption> +-#include <QTextBlock> +-#include <QTextBlockFormat> +-#include <QGuiApplication> +- +-USMAboutDialog::USMAboutDialog(QWidget *parent) +- : QDialog(parent) +-{ +- setFixedSize(420, 486); +- +- //XAtomHelper::getInstance()->setUKUIDecoraiontHint(this->winId(), true); +- QString platform = QGuiApplication::platformName(); +- if (!platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive)) { +- MotifWmHints hints; +- hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; +- hints.functions = MWM_FUNC_ALL; +- hints.decorations = MWM_DECOR_BORDER; +- XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); +- } +- m_fFontSize = DEFAULT_FONT_SIZE; +- initWidgets(); +- initConnections(); +-} +- +-USMAboutDialog::~USMAboutDialog() +-{ +- if (m_styleSettings) { +- delete m_styleSettings; +- m_styleSettings = nullptr; +- } +-} +- +-bool USMAboutDialog::initWidgets() +-{ +- m_mainVLayout = new QVBoxLayout(); +- m_titleLayout = new QHBoxLayout(); +- m_logoIconLayout = new QHBoxLayout(); +- m_appNameLayout = new QHBoxLayout(); +- m_versionLayout = new QHBoxLayout(); +- m_introduceLayout = new QHBoxLayout(); +- m_supportLayout = new QHBoxLayout(); +- +- m_mainVLayout->setContentsMargins(0, 0, 0, 0); +- m_mainVLayout->setSpacing(0); +- m_titleLayout->setContentsMargins(8, 4, 4, 4); +- m_titleLayout->setSpacing(0); +- m_logoIconLayout->setContentsMargins(24, 0, 24, 0); +- m_logoIconLayout->setSpacing(0); +- m_appNameLayout->setContentsMargins(24, 0, 24, 0); +- m_appNameLayout->setSpacing(0); +- m_versionLayout->setContentsMargins(24, 0, 24, 0); +- m_versionLayout->setSpacing(0); +- m_introduceLayout->setContentsMargins(24, 0, 24, 0); +- m_introduceLayout->setSpacing(0); +- m_supportLayout->setContentsMargins(24, 0, 24, 0); +- m_supportLayout->setSpacing(8); +- +- initTitleWidget(); +- +- initContentWidget(); +- +- initSupportWidget(); +- +- m_mainVLayout->addLayout(m_titleLayout); +- m_mainVLayout->addSpacing(34); +- m_mainVLayout->addLayout(m_logoIconLayout); +- m_mainVLayout->addSpacing(12); +- m_mainVLayout->addLayout(m_appNameLayout); +- m_mainVLayout->addSpacing(8); +- m_mainVLayout->addLayout(m_versionLayout); +- m_mainVLayout->addSpacing(8); +- m_mainVLayout->addLayout(m_introduceLayout); +- m_mainVLayout->addStretch(); +- m_mainVLayout->addLayout(m_supportLayout); +- m_mainVLayout->addSpacing(40); +- +- this->setLayout(m_mainVLayout); +- +- const QByteArray id(THEME_QT_SCHEMA); +- if(QGSettings::isSchemaInstalled(id)) +- { +- m_styleSettings = new QGSettings(id); +- } +- initThemeStyle(); +- +- return true; +-} +- +-bool USMAboutDialog::initTitleWidget() +-{ +- QIcon titleIcon = QIcon::fromTheme("ukui-system-monitor"); +- +- m_labelTitleIcon = new QLabel(); +- m_labelTitleIcon->setPixmap(titleIcon.pixmap(QSize(24, 24))); +- +- m_labelTitleText = new QLabel(tr("Kylin System Monitor")); +- +- m_btnClose = new QPushButton(); +- m_btnClose->setIcon(QIcon::fromTheme("window-close-symbolic")); +- m_btnClose->setProperty("isWindowButton", 0x02); +- m_btnClose->setProperty("useIconHighlightEffect", 0x08); +- m_btnClose->setFlat(true); +- m_btnClose->setFixedSize(30, 30); +- +- m_titleLayout->addWidget(m_labelTitleIcon); +- m_titleLayout->addSpacing(16); +- m_titleLayout->addWidget(m_labelTitleText); +- m_titleLayout->addStretch(); +- m_titleLayout->addWidget(m_btnClose); +- return true; +-} +- +-bool USMAboutDialog::initContentWidget() +-{ +- QIcon titleIcon = QIcon::fromTheme("ukui-system-monitor"); +- m_labelLogoIcon = new QLabel(); +- m_labelLogoIcon->setPixmap(titleIcon.pixmap(QSize(96, 96))); +- m_logoIconLayout->addStretch(); +- m_logoIconLayout->addWidget(m_labelLogoIcon); +- m_logoIconLayout->addStretch(); +- +- m_labelAppName = new QLabel(tr("Kylin System Monitor")); +- m_appNameLayout->addStretch(); +- m_appNameLayout->addWidget(m_labelAppName); +- m_appNameLayout->addStretch(); +- +- m_labelVersion = new QLabel(tr("version: ") + getUsmVersion()); +- m_versionLayout->addStretch(); +- m_versionLayout->addWidget(m_labelVersion); +- m_versionLayout->addStretch(); +- +- m_labelIntroduce = new QLabel(tr("System monitor is a desktop application that face desktop users of Kylin operating system," +- "It meets the needs of users to monitor the system process, system resources and file system")); +- m_labelIntroduce->setMinimumSize(372, 0); +- m_labelIntroduce->setMaximumSize(372, 16777215); +- m_labelIntroduce->setWordWrap(true); +- m_labelIntroduce->setAlignment(Qt::AlignLeft); +- m_introduceLayout->addWidget(m_labelIntroduce); +- return true; +-} +- +-bool USMAboutDialog::initSupportWidget() +-{ +- m_labelSupport = new QLabel(tr("Service and support team:")); +- +- m_supportLayout->addWidget(m_labelSupport); +- +- m_btnSupportUrl = new QPushButton("support@kylinos.cn"); +- m_btnSupportUrl->setFocusPolicy(Qt::NoFocus); +- m_btnSupportUrl->setCursor( QCursor(Qt::PointingHandCursor)); +- m_btnSupportUrl->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;text-decoration: underline;} "); +- +- m_supportLayout->addWidget(m_btnSupportUrl); +- m_supportLayout->setAlignment(Qt::AlignLeft); +- connect(m_btnSupportUrl, &QPushButton::clicked, this,[=] { +- QDesktopServices::openUrl(QUrl("mailto:support@kylinos.cn")); +- }); +- return true; +-} +- +-bool USMAboutDialog::initConnections() +-{ +- connect(m_btnClose, &QPushButton::clicked, this, [=]() { +- this->close(); +- }); +- return true; +-} +- +-void USMAboutDialog::initThemeStyle() +-{ +- if (!m_styleSettings) { +- return; +- } +- connect(m_styleSettings,&QGSettings::changed,[=](QString key) +- { +- if ("iconThemeName" == key) { +- this->setWindowIcon(QIcon::fromTheme("ukui-system-monitor")); +- if (m_labelTitleIcon) +- m_labelTitleIcon->setPixmap(QIcon::fromTheme("ukui-system-monitor").pixmap(24,24)); +- if (m_labelLogoIcon) +- m_labelLogoIcon->setPixmap(QIcon::fromTheme("ukui-system-monitor").pixmap(96,96)); +- } else if ("systemFont" == key || "systemFontSize" == key) { +- m_fFontSize = m_styleSettings->get(FONT_SIZE).toString().toFloat(); +- onThemeFontChange(m_fFontSize); +- } +- }); +- m_fFontSize = m_styleSettings->get(FONT_SIZE).toString().toFloat(); +- onThemeFontChange(m_fFontSize); +-} +- +-void USMAboutDialog::setFontSize(QLabel *label,int fontSize) +-{ +- if (!label) +- return; +- QFont font = label->font(); +- font.setPointSize(fontSize); +- label->setFont(font); +-} +- +-void USMAboutDialog::setFontSize(QTextEdit *txtEdit,int fontSize) +-{ +- if (!txtEdit) +- return; +- QFont font = txtEdit->font(); +- font.setPointSize(fontSize); +- txtEdit->setFont(font); +-} +- +-void USMAboutDialog::setFontSize(QPushButton *btn,int fontSize) +-{ +- if (!btn) +- return; +- QFont font = btn->font(); +- font.setPointSize(fontSize); +- btn->setFont(font); +-} +- +-void USMAboutDialog::paintEvent(QPaintEvent *event) +-{ +- QPainterPath path; +- QPainter painter(this); +- +- path.addRect(this->rect()); +- path.setFillRule(Qt::WindingFill); +- painter.setBrush(this->palette().base()); +- painter.setPen(Qt::transparent); +- painter.drawPath(path); +- QDialog::paintEvent(event); +-} +- +-void USMAboutDialog::onThemeFontChange(float fFontSize) +-{ +- if (m_btnSupportUrl) { +- setFontSize(m_btnSupportUrl, fFontSize); +- } +- if (m_labelAppName) { +- setFontSize(m_labelAppName, fFontSize * 1.3); +- } +-} +diff --git a/src/dialog/usmaboutdialog.h b/src/dialog/usmaboutdialog.h +deleted file mode 100644 +index 1ae1b49..0000000 +--- a/src/dialog/usmaboutdialog.h ++++ /dev/null +@@ -1,77 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#ifndef USMABOUTDIALOG_H +-#define USMABOUTDIALOG_H +- +-#include <QDialog> +-#include <QLabel> +-#include <QPushButton> +-#include <QHBoxLayout> +-#include <QGSettings> +-#include <QTextEdit> +- +-class USMAboutDialog : public QDialog +-{ +- Q_OBJECT +-public: +- explicit USMAboutDialog(QWidget *parent = nullptr); +- virtual ~USMAboutDialog(); +- +-protected: +- void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; +- +-private: +- bool initWidgets(); +- bool initTitleWidget(); +- bool initContentWidget(); +- bool initSupportWidget(); +- bool initConnections(); +- +- void initThemeStyle(); +- void setFontSize(QLabel *label,int fontSize); +- void setFontSize(QTextEdit *txtEdit,int fontSize); +- void setFontSize(QPushButton *btn,int fontSize); +- void onThemeFontChange(float fFontSize); +- +-private: +- QLabel *m_labelTitleIcon = nullptr; +- QLabel *m_labelTitleText = nullptr; +- QPushButton *m_btnClose = nullptr; +- QLabel *m_labelLogoIcon = nullptr; +- QLabel *m_labelAppName = nullptr; +- QLabel *m_labelVersion = nullptr; +- QLabel *m_labelIntroduce = nullptr; +- QLabel *m_labelSupport = nullptr; +- QPushButton *m_btnSupportUrl = nullptr; +- +- QHBoxLayout *m_logoIconLayout = nullptr; +- QHBoxLayout *m_appNameLayout = nullptr; +- QHBoxLayout *m_versionLayout = nullptr; +- QHBoxLayout *m_introduceLayout = nullptr; +- QHBoxLayout *m_supportLayout = nullptr; +- QHBoxLayout *m_titleLayout = nullptr; +- QVBoxLayout *m_mainVLayout = nullptr; +- +- QGSettings *m_styleSettings = nullptr; +- float m_fFontSize; +-}; +- +-#endif // USMABOUTDIALOG_H +diff --git a/src/filesystem/filesystemworker.cpp b/src/filesystem/filesystemworker.cpp +index 879e360..ebc7d52 100644 +--- a/src/filesystem/filesystemworker.cpp ++++ b/src/filesystem/filesystemworker.cpp +@@ -136,11 +136,6 @@ DISK_INFO add_disk(const glibtop_mountentry *entry, gboolean show_all_fs) + return disk; + } + +-//void hello(gpointer data) +-//{ +-// g_print ("Hello World\n"); +-//} +- + FileSystemWorker::FileSystemWorker(QObject *parent) + : QObject(parent) + { +@@ -264,15 +259,6 @@ void FileSystemWorker::updateDiskInfo(QString devname, FileSystemData& info) + } + } + +-void FileSystemWorker::removeDiskItem(const QString &devname) +-{ +- Q_UNUSED(devname); +- // FileSystemData info; +- // if (getDiskInfo(devname, info)) { +- // m_diskInfoList.remove(devname); +- // } +-} +- + bool FileSystemWorker::isDeviceContains(const QString &devname) + { + return m_diskInfoList.keys().contains(devname); +diff --git a/src/filesystem/filesystemworker.h b/src/filesystem/filesystemworker.h +index 179d9d9..51ea5c5 100644 +--- a/src/filesystem/filesystemworker.h ++++ b/src/filesystem/filesystemworker.h +@@ -36,14 +36,11 @@ public: + explicit FileSystemWorker(QObject *parent = 0); + ~FileSystemWorker(); + +- void removeDiskItem(const QString &devname); +- + bool getDiskInfo(const QString &devname, FileSystemData& info); + QList<FileSystemData> diskInfoList() const; + QList<QString> diskDevNameList() const; + void addDiskInfo(const QString &devname, FileSystemData& info); + void updateDiskInfo(QString devname, FileSystemData& info); +- void removeDiskInfo(const QString &devname); + bool isDeviceContains(const QString &devname); + + public slots: +diff --git a/src/imageutil.cpp b/src/imageutil.cpp +deleted file mode 100644 +index 475d16f..0000000 +--- a/src/imageutil.cpp ++++ /dev/null +@@ -1,83 +0,0 @@ +-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +- * +- * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +- * +- */ +- +-#include "imageutil.h" +- +-#include <QPainter> +- +-const QPixmap ImageUtil::loadSvg(const QString &path, const QString color, int size) +-{ +- int origSize = size; +- const auto ratio = qApp->devicePixelRatio(); +- if ( 2 == ratio) { +- size += origSize; +- } else if (3 == ratio) { +- size += origSize; +- } else { +- size = origSize * ratio; +- } +- QPixmap pixmap(size, size); +- QSvgRenderer renderer(path); +- pixmap.fill(Qt::transparent); +- +- QPainter painter; +- painter.begin(&pixmap); +- renderer.render(&painter); +- painter.end(); +- +- pixmap.setDevicePixelRatio(ratio); +- return drawSymbolicColoredPixmap(pixmap, color); +-} +- +-QPixmap ImageUtil::drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor) +-{ +- QImage img = source.toImage(); +- for (int x = 0; x < img.width(); x++) { +- for (int y = 0; y < img.height(); y++) { +- auto color = img.pixelColor(x, y); +- if (color.alpha() > 0) { +- if ( "white" == cgColor) { +- color.setRed(255); +- color.setGreen(255); +- color.setBlue(255); +- img.setPixelColor(x, y, color); +- } else if( "black" == cgColor) { +- color.setRed(0); +- color.setGreen(0); +- color.setBlue(0); +- img.setPixelColor(x, y, color); +- } else if ("gray"== cgColor) { +- color.setRed(152); +- color.setGreen(163); +- color.setBlue(164); +- img.setPixelColor(x, y, color); +- } else if ("blue" == cgColor){ +- color.setRed(61); +- color.setGreen(107); +- color.setBlue(229); +- img.setPixelColor(x, y, color); +- } else { +- return source; +- } +- } +- } +- } +- return QPixmap::fromImage(img); +-} +diff --git a/src/imageutil.h b/src/imageutil.h +deleted file mode 100644 +index 92c09d8..0000000 +--- a/src/imageutil.h ++++ /dev/null +@@ -1,35 +0,0 @@ +-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +- * +- * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +- * +- */ +- +-#ifndef IMAGEUTIL_H +-#define IMAGEUTIL_H +- +-#include <QPixmap> +-#include <QSvgRenderer> +-#include <QApplication> +- +-class ImageUtil +-{ +-public: +- static const QPixmap loadSvg(const QString &path, const QString color, int size = 16); +- static QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); +-}; +- +-#endif // IMAGEUTIL_H +diff --git a/src/kleftsideitem.cpp b/src/kleftsideitem.cpp +deleted file mode 100644 +index 3fe6a2c..0000000 +--- a/src/kleftsideitem.cpp ++++ /dev/null +@@ -1,238 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#include "kleftsideitem.h" +- +-#include <QIcon> +-#include <QPixmap> +-#include <QVariant> +-#include <QEvent> +- +-#include "macro.h" +-#include "util.h" +-#include "imageutil.h" +- +-KLeftSideItem::KLeftSideItem(QWidget *parent) +- : QPushButton(parent) +-{ +- m_strIcon = ""; +- m_strText = ""; +- this->setFlat(true); +- initUI(); +-} +- +-KLeftSideItem::KLeftSideItem(QString strText, QString strIcon, QWidget *parent) +- : QPushButton(parent) +-{ +- m_strIcon = strIcon; +- m_strText = strText; +- this->setFlat(true); +- initUI(); +-} +- +-KLeftSideItem::~KLeftSideItem() +-{ +- if (m_styleSettings) { +- delete m_styleSettings; +- m_styleSettings = nullptr; +- } +-} +- +-void KLeftSideItem::initUI() +-{ +- installEventFilter(this); +- setProperty("useButtonPalette", true); +- m_layoutMain = new QHBoxLayout(); +- m_layoutMain->setContentsMargins(16,6,16,6); +- m_layoutMain->setSpacing(8); +- +- m_labelIcon = new QLabel(); +- m_layoutMain->addWidget(m_labelIcon); +- +- m_labelText = new QLabel(); +- setText(m_strText); +- m_layoutMain->addWidget(m_labelText); +- +- m_layoutMain->addStretch(); +- this->setLayout(m_layoutMain); +- initStyleTheme(); +- setIcon(m_strIcon); +- +- +- if (QGSettings::isSchemaInstalled("org.ukui.style")) { +- QGSettings *qtSettings = new QGSettings("org.ukui.style", QByteArray(), this); +- if (qtSettings->keys().contains("styleName")) { +- hoverColor = btnHoverColor(qtSettings->get("style-name").toString(), true); +- clickColor = btnHoverColor(qtSettings->get("style-name").toString(), false); +- this->setStyleSheet(QString("KLeftSideItem:hover{background-color:%1;border-radius: 6px;}" +- "KLeftSideItem:pressed{background-color:%2;border-radius: 6px;}").arg(hoverColor).arg(clickColor)); +- +- connect(qtSettings, &QGSettings::changed, this, [=](const QString &key) { +- if (key == "styleName") { +- hoverColor = this->btnHoverColor(qtSettings->get("style-name").toString(), true); +- clickColor = btnHoverColor(qtSettings->get("style-name").toString(), false); +- if (!this->isChecked()) +- this->setStyleSheet(QString("KLeftSideItem:hover{background-color:%1;border-radius: 6px;}" +- "KLeftSideItem:pressed{background-color:%2;border-radius: 6px;}").arg(hoverColor).arg(clickColor)); +- } else if (key == "themeColor" && this->isChecked()) { +- this->toggled(true); +- } +- }); +- } +- } +- +- connect(this, &QPushButton::toggled, this, [=](bool checked) { +- if (checked) { +- this->setStyleSheet("KLeftSideItem:checked{background-color: palette(highlight);border-radius: 6px;}"); +- m_labelText->setStyleSheet("color: white"); +- m_isNormal = false; +- } else { +- this->setStyleSheet(QString("KLeftSideItem:hover{background-color:%1;border-radius: 6px;}" +- "KLeftSideItem:pressed{background-color:%2;border-radius: 6px;}").arg(hoverColor).arg(clickColor)); +- if (!m_isHover) { +- m_isNormal = true; +- } +- m_labelText->setStyleSheet("color: palette(windowtext)"); +- } +- setIcon(m_strIcon); +- }); +-} +- +-void KLeftSideItem::initStyleTheme() +-{ +- const QByteArray idd(THEME_QT_SCHEMA); +- if(QGSettings::isSchemaInstalled(idd)) { +- m_styleSettings = new QGSettings(idd); +- } +- if (m_styleSettings) { +- connect(m_styleSettings, &QGSettings::changed, this, [=](const QString &key) { +- if (key == "styleName") { +- auto styleNameValue = m_styleSettings->get("styleName"); +- if (styleNameValue.isValid()) { +- m_strThemeName = styleNameValue.toString(); +- setIcon(m_strIcon); +- } +- } else if (key == "systemFontSize" || key == "systemFont") { +- auto styleFontSizeValue = m_styleSettings->get("systemFontSize"); +- if (styleFontSizeValue.isValid()) { +- this->setText(m_strText); +- } +- QFont fontTitle = this->font(); +- m_labelText->setFont(fontTitle); +- } +- }); +- auto styleNameValue = m_styleSettings->get("styleName"); +- if (styleNameValue.isValid()) { +- m_strThemeName = styleNameValue.toString(); +- } +- auto styleFontSizeValue = m_styleSettings->get("systemFontSize"); +- if (styleFontSizeValue.isValid()) { +- this->setText(m_strText); +- } +- } +-} +- +-void KLeftSideItem::setText(QString &strText) +-{ +- m_strText = strText; +- if (!m_strText.isEmpty()) { +- QString ShowValue = getElidedText(m_labelText->font(), m_strText, width()-60); // 16+16+8+16 + 4 +- m_labelText->setText(ShowValue); +- if (ShowValue != m_strText) { +- setToolTip(m_strText); +- } else { +- setToolTip(""); +- } +- m_labelText->show(); +- } else { +- m_labelText->hide(); +- } +-} +- +-void KLeftSideItem::setIcon(QString &strIcon) +-{ +- m_strIcon = strIcon; +- QPixmap pixmap; +- if (m_strThemeName == "ukui-dark" || m_strThemeName == "ukui-black") { +- if (m_isNormal) { +- pixmap = ImageUtil::loadSvg(m_strIcon, "white", 16); +- } else { +- pixmap = ImageUtil::loadSvg(m_strIcon, "white", 16); +- } +- } else { // "ukui-default" "ukui-white" "ukui-light" "ukui" +- if (m_isNormal) { +- pixmap = ImageUtil::loadSvg(m_strIcon, "black", 16); +- } else { +- pixmap = ImageUtil::loadSvg(m_strIcon, "white", 16); +- } +- } +- if (!pixmap.isNull()) { +- m_labelIcon->setPixmap(pixmap); +- m_labelIcon->show(); +- } else { +- m_labelIcon->hide(); +- } +-} +- +-bool KLeftSideItem::eventFilter(QObject *obj, QEvent *event) +-{ +- if (obj == this) { +- switch (event->type()) { +- case QEvent::HoverEnter: +- m_isHover = true; +- setIcon(m_strIcon); +- break; +- case QEvent::HoverLeave: +- m_isHover = false; +- setIcon(m_strIcon); +- break; +- default: +- break; +- } +- } +- return QPushButton::eventFilter(obj, event); +-} +- +-QString KLeftSideItem::btnHoverColor(QString styleName, bool hoverFlag) +-{ +- QColor color1 = palette().color(QPalette::Active, QPalette::Button); +- QColor color2 = palette().color(QPalette::Active, QPalette::BrightText); +- QColor color; +- qreal r,g,b,a; +- QString hoverColor; +- if (((styleName.contains("dark") || styleName.contains("black")) && hoverFlag) || +- ((!styleName.contains("dark") && !styleName.contains("black")) && !hoverFlag)) { +- r = color1.redF() * 0.8 + color2.redF() * 0.2; +- g = color1.greenF() * 0.8 + color2.greenF() * 0.2; +- b = color1.blueF() * 0.8 + color2.blueF() * 0.2; +- a = color1.alphaF() * 0.8 + color2.alphaF() * 0.2; +- } else { +- r = color1.redF() * 0.95 + color2.redF() * 0.05; +- g = color1.greenF() * 0.95 + color2.greenF() * 0.05; +- b = color1.blueF() * 0.95 + color2.blueF() * 0.05; +- a = color1.alphaF() * 0.95 + color2.alphaF() * 0.05; +- } +- color = QColor::fromRgbF(r, g, b, a); +- hoverColor = QString("rgba(%1, %2, %3, %4)").arg(color.red()) +- .arg(color.green()) +- .arg(color.blue()) +- .arg(color.alpha()); +- return hoverColor; +-} +diff --git a/src/kleftsideitem.h b/src/kleftsideitem.h +deleted file mode 100644 +index e7df605..0000000 +--- a/src/kleftsideitem.h ++++ /dev/null +@@ -1,63 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#ifndef KLEFTSIDEITEM_H +-#define KLEFTSIDEITEM_H +- +-#include <QPushButton> +-#include <QLabel> +-#include <QHBoxLayout> +-#include <qgsettings.h> +- +-class KLeftSideItem : public QPushButton +-{ +- Q_OBJECT +-public: +- explicit KLeftSideItem(QWidget *parent = nullptr); +- KLeftSideItem(QString strText, QString strIcon, QWidget *parent = nullptr); +- virtual ~KLeftSideItem(); +- +- void initUI(); +- void setText(QString &strText); +- void setIcon(QString &strIcon); +- QString btnHoverColor(QString styleName, bool hoverFlag); +- +-protected: +- bool eventFilter(QObject *obj, QEvent *event) override; //事件过滤 +- +-private: +- void initStyleTheme(); +- +-private: +- QHBoxLayout *m_layoutMain = nullptr; +- QLabel *m_labelIcon = nullptr; +- QLabel *m_labelText = nullptr; +- +- QString m_strIcon; +- QString m_strText; +- QGSettings *m_styleSettings = nullptr; +- QString m_strThemeName = ""; +- bool m_isNormal = true; +- bool m_isHover = false; +- QString hoverColor; +- QString clickColor; +-}; +- +-#endif // KLEFTSIDEITEM_H +diff --git a/src/kleftwidget.h b/src/kleftwidget.h +index 8e5114f..2908848 100644 +--- a/src/kleftwidget.h ++++ b/src/kleftwidget.h +@@ -32,7 +32,6 @@ + #include <QTimer> + #include <QScrollArea> + +-#include "kleftsideitem.h" + #include "sysresource/cpuhistorywidget.h" + #include "sysresource/memhistorywidget.h" + #include "sysresource/nethistorywidget.h" +diff --git a/src/krightwidget.cpp b/src/krightwidget.cpp +index 34b5be8..70c1a4b 100644 +--- a/src/krightwidget.cpp ++++ b/src/krightwidget.cpp +@@ -70,12 +70,10 @@ void KRightWidget::initUI() + m_searchLayout->setSpacing(0); + + // 初始化控件 +- m_btnOption = new QToolButton(this); +- m_btnOption->setToolTip(tr("Option")); +- m_btnOption->setProperty("isWindowButton", 0x01); +- m_btnOption->setProperty("useIconHighlightEffect", 0x2); +- m_btnOption->setIcon(QIcon::fromTheme("open-menu-symbolic")); +- m_btnOption->setAutoRaise(true); ++ m_mainMenu = new KMenuButton(); ++ m_mainMenu->themeAction()->setVisible(false); ++ m_mainMenu->settingAction()->setVisible(false); ++ m_mainMenu->feedbackAction()->setVisible(true); + m_btnMin = new QToolButton(this); + m_btnMin->setToolTip(tr("Minimize")); + m_btnMin->setProperty("isWindowButton", 0x01); +@@ -95,17 +93,7 @@ void KRightWidget::initUI() + m_btnClose->setAutoRaise(true); + m_btnClose->setIcon(QIcon::fromTheme("window-close-symbolic")); + +- m_mainMenu = new QMenu(this); +- m_mainMenu->setMinimumWidth(160); +- m_mainMenu->addAction(tr("Help")); +- m_mainMenu->addAction(tr("About")); +- m_mainMenu->addAction(tr("Exit")); +- m_btnOption->setMenu(m_mainMenu); +- m_btnOption->setPopupMode(QToolButton::InstantPopup); +- +- connect(m_mainMenu,&QMenu::triggered,this,[=](QAction *action){ +- qDebug() << Q_FUNC_INFO << action->text(); +- if(action->text() == tr("About")){ ++ connect(m_mainMenu->aboutAction(), &QAction::triggered, this, [=]{ + KAboutDialog *k_aboutDialog = new KAboutDialog(this); + k_aboutDialog->setAppIcon(QIcon::fromTheme("ukui-system-monitor")); + k_aboutDialog->setWindowTitle(tr("Kylin System Monitor")); +@@ -113,17 +101,10 @@ void KRightWidget::initUI() + k_aboutDialog->setAppVersion(getUsmVersion()); + k_aboutDialog->setAppSupport(k_aboutDialog->appSupport()); + k_aboutDialog->exec(); +- }else if(action->text() == tr("Help")){ +- QString service_name = "com.kylinUserGuide.hotel_" + QString::number(getuid()); +- QDBusInterface *interface = new QDBusInterface(service_name, +- KYLIN_USER_GUIDE_PATH, +- KYLIN_USER_GUIDE_INTERFACE, +- QDBusConnection::sessionBus(), +- this); +- QDBusMessage msg = interface->call("showGuide", "ukui-system-monitor"); +- }else if(action->text() == tr("Exit")){ +- qApp->exit(); +- } ++ }); ++ connect(m_mainMenu->assistAction(), &QAction::triggered, this, &KRightWidget::showUserGuide); ++ connect(m_mainMenu->quitAction(), &QAction::triggered, this, [=]{ ++ qApp->exit(); + }); + + // 搜索框 +@@ -146,7 +127,7 @@ void KRightWidget::initUI() + + m_titleLayout->setSpacing(4); + m_titleLayout->addLayout(m_searchLayout); +- m_titleLayout->addWidget(m_btnOption); ++ m_titleLayout->addWidget(m_mainMenu); + m_titleLayout->addWidget(m_btnMin); + m_titleLayout->addWidget(m_btnMax); + m_titleLayout->addWidget(m_btnClose); +@@ -191,15 +172,6 @@ void KRightWidget::initConnections() + connect(m_searchEditNew,&QLineEdit::textChanged,this,&KRightWidget::handleSearchTextChanged,Qt::QueuedConnection); + } + +-void KRightWidget::createAboutDialog() +-{ +- QApplication::setOverrideCursor(Qt::WaitCursor); +- +- m_aboutDlg = new USMAboutDialog(this); +- +- QApplication::restoreOverrideCursor(); +-} +- + void KRightWidget::onMinBtnClicked() + { + emit minimizeWindow(); +@@ -314,18 +286,27 @@ void KRightWidget::handleSearchTextChanged() + m_searchTimer->start(300); + } + ++void KRightWidget::showUserGuide() ++{ ++ QString service_name = "com.kylinUserGuide.hotel_" + QString::number(getuid()); ++ QDBusInterface interface(service_name, ++ KYLIN_USER_GUIDE_PATH, ++ KYLIN_USER_GUIDE_INTERFACE, ++ QDBusConnection::sessionBus(), ++ this); ++ QDBusMessage msg = interface.call("showGuide", "ukui-system-monitor"); ++} ++ + void KRightWidget::changeTitleWidget(bool isTablet) + { + if (isTablet) { + m_titleWidget->setFixedHeight(64); +- m_btnOption->setFixedSize(48, 48); + m_btnMin->setFixedSize(48, 48); + m_btnClose->setFixedSize(48, 48); + m_btnMax->setVisible(false); + m_searchEditNew->setFixedSize(280,40); + } else { + m_titleWidget->setFixedHeight(40); +- m_btnOption->setFixedSize(30, 30); + m_btnMin->setFixedSize(30, 30); + m_btnMax->setFixedSize(30, 30); + m_btnClose->setFixedSize(30, 30); +diff --git a/src/krightwidget.h b/src/krightwidget.h +index f8bb155..66565a9 100644 +--- a/src/krightwidget.h ++++ b/src/krightwidget.h +@@ -31,10 +31,9 @@ + #include <QTimer> + #include <QGSettings> + +-#include "dialog/usmaboutdialog.h" + #include "kaboutdialog.h" + #include "ksearchlineedit.h" +- ++#include "kmenubutton.h" + using namespace kdk; + + class KRightWidget : public QWidget +@@ -46,7 +45,6 @@ public: + + void initUI(); + void initConnections(); +- void createAboutDialog(); + + void addPanel(QWidget* pWidget, QString strName, QString strIcon, int nPanelIdx = -1); + int currentIndex(); +@@ -63,6 +61,7 @@ public slots: + void animationFinishedSlot(); + void onRefreshSearchResult(); + void handleSearchTextChanged(); ++ void showUserGuide(); + + signals: + void maximizeWindow(); +@@ -79,15 +78,12 @@ private: + + private: + QWidget* m_titleWidget = nullptr; +- QToolButton *m_btnOption = nullptr; + QToolButton *m_btnMin = nullptr; + QToolButton *m_btnMax = nullptr; + QToolButton *m_btnClose = nullptr; +- QMenu *m_mainMenu = nullptr; ++ KMenuButton *m_mainMenu = nullptr; + QStackedWidget *m_stackedWidget = nullptr; + +- USMAboutDialog *m_aboutDlg = nullptr; +- + QVBoxLayout *m_mainLayout = nullptr; + QHBoxLayout *m_titleLayout = nullptr; + QHBoxLayout *m_searchLayout = nullptr; +diff --git a/src/main.cpp b/src/main.cpp +index a156091..91f2e39 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -26,7 +26,6 @@ + #include <KWindowEffects> + #include <ukui-log4qt.h> + +-#include "xatom-helper.h" + #include "mainwindow.h" + + #include <execinfo.h> +diff --git a/src/process/process_list.cpp b/src/process/process_list.cpp +index 443d240..8d54ca7 100644 +--- a/src/process/process_list.cpp ++++ b/src/process/process_list.cpp +@@ -23,7 +23,6 @@ + #include "../desktopfileinfo.h" + + #include <QDebug> +-#include <QApplication> + + #include <unistd.h> + #include <systemd/sd-login.h> +diff --git a/src/process/process_oplimit.cpp b/src/process/process_oplimit.cpp +deleted file mode 100644 +index ef3f73d..0000000 +--- a/src/process/process_oplimit.cpp ++++ /dev/null +@@ -1,152 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#include "process_oplimit.h" +- +-#include <stdio.h> +-#include <QStringList> +-#include <QRegExp> +-#include <QXmlStreamReader> +-#include <QFile> +-#include <QFileInfo> +-#include <QDebug> +- +-ProcessOpLimit::ProcessOpLimit(QObject *parent) +- : QObject(parent) +-{ +- m_isInited = false; +- m_listProtected.clear(); +-} +- +-ProcessOpLimit::~ProcessOpLimit() +-{ +- +-} +- +-void ProcessOpLimit::init() +-{ +- if (!m_isInited) { +- m_fsWatcher.addPath(KSEC_PROCPROTECTED_FILE); +- connect(&m_fsWatcher,SIGNAL(fileChanged(QString)),this, SLOT(onFileChanged(QString))); +- parseProtectedXml(KSEC_PROCPROTECTED_FILE, m_listProtected); +- m_isInited = true; +- } +-} +- +-bool ProcessOpLimit::isProtectedProc(QString strCmd) +-{ +- if (!isAppSecurityOpened()) { +- return false; +- } +- init(); +- QStringList strList = strCmd.split(QRegExp("\\s+")); +- if (!strList.isEmpty()) { +- for (int n = 0; n < m_listProtected.size(); n ++) { +- if (m_listProtected.contains(strList[0])) { +- return true; +- } +- } +- } +- return false; +-} +- +-void ProcessOpLimit::parseProtectedXml(QString strFilePath, QList<QString>& listPath) +-{ +- QFile file(strFilePath); +- listPath.clear(); +- if (!file.open(QFile::ReadOnly | QFile::Text)) { +- qWarning() << "Error: Cannot read file " << strFilePath <<",errMsg:" +- << file.errorString(); +- return; +- } +- QXmlStreamReader reader; +- reader.setDevice(&file); +- +- reader.readNext(); +- while (!reader.atEnd()) { +- if (reader.isStartElement()) { +- if (reader.name() == "ppro_root") { +- reader.readNext(); +- while (!reader.atEnd()) { +- if (reader.isEndElement()) { +- reader.readNext(); +- continue; +- } +- if (reader.isStartElement()) { +- if (reader.name() == "ppro_node") { +- QStringRef strPathRef = reader.attributes().value("path"); +- if (!strPathRef.isNull()) { +- listPath.append(strPathRef.toString()); +- } +- reader.readNext(); +- while (!reader.atEnd()) { +- if (reader.isEndElement()) { +- reader.readNext(); +- break; +- } +- if (reader.isStartElement()) { +- if (reader.name() == "type") { +- QString strType = reader.readElementText(); +- if (!strType.isEmpty()) { +- int nType = strType.toInt(); +- if (nType == 1) { // 防杀死 +- } +- } +- } else if (reader.name() == "hash") { +- } +- } +- reader.readNext(); +- } +- continue; +- } +- } +- reader.readNext(); +- } +- continue; +- } +- } +- reader.readNext(); +- } +- file.close(); +- qInfo()<<"PprocList:"<<listPath; +-} +- +-void ProcessOpLimit::onFileChanged(QString strFile) +-{ +- qInfo()<<"PProcsChanged:"<<strFile; +- if (strFile == KSEC_PROCPROTECTED_FILE) { +- parseProtectedXml(KSEC_PROCPROTECTED_FILE, m_listProtected); +- } +-} +- +-bool ProcessOpLimit::isAppSecurityOpened() +-{ +- FILE *pFile = fopen(KSEC_PROCPROTECTED_SWITCH,"r"); +- if (pFile) { +- char chSwitch = 0; +- size_t readSize = fread(&chSwitch, sizeof(char), 1, pFile); +- fclose(pFile); +- pFile = NULL; +- if (readSize > 0 && chSwitch != '0') { +- return true; +- } +- } +- return false; +-} +diff --git a/src/process/process_oplimit.h b/src/process/process_oplimit.h +deleted file mode 100644 +index 3abab19..0000000 +--- a/src/process/process_oplimit.h ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* +- * Copyright (C) 2021 KylinSoft Co., Ltd. +- * +- * Authors: +- * Yang Min yangmin@kylinos.cn +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#ifndef __PROCESS_OPLIMIT_H__ +-#define __PROCESS_OPLIMIT_H__ +- +-#include <QObject> +-#include <QList> +-#include <QFileSystemWatcher> +- +-#define KSEC_PROCPROTECTED_FILE "/etc/kysec/ppro/ppro.xml" +-#define KSEC_PROCPROTECTED_SWITCH "/sys/kernel/security/kysec/ppro" +- +-class ProcessOpLimit : public QObject +-{ +- Q_OBJECT +-public: +- ProcessOpLimit(QObject *parent = nullptr); +- ~ProcessOpLimit(); +- +- bool isProtectedProc(QString strCmd); +- void parseProtectedXml(QString strFilePath, QList<QString>& listPath); +- +-public slots: +- void onFileChanged(QString); +- +-private: +- void init(); +- bool isAppSecurityOpened(); +- +-private: +- QList<QString> m_listProtected; +- bool m_isInited; +- QFileSystemWatcher m_fsWatcher; +-}; +- +-#endif // __PROCESS_OPLIMIT_H__ +diff --git a/src/process/processtableview.cpp b/src/process/processtableview.cpp +index f4a6993..2ee9bd2 100644 +--- a/src/process/processtableview.cpp ++++ b/src/process/processtableview.cpp +@@ -81,7 +81,6 @@ ProcessTableView::ProcessTableView(QSettings* proSettings, QWidget *parent) + // start process monitor thread + ProcessMonitorThread::instance()->start(); + +- m_procOpLimit = new ProcessOpLimit(); + QDir dir; + // 当前用户名 + m_user = dir.home().dirName(); +@@ -95,10 +94,6 @@ ProcessTableView::~ProcessTableView() + { + // start process monitor thread + ProcessMonitorThread::instance()->stop(); +- if (m_procOpLimit) { +- delete m_procOpLimit; +- m_procOpLimit = nullptr; +- } + } + + void ProcessTableView::onWndClose() +@@ -837,8 +832,8 @@ void ProcessTableView::changeProcPriority(int nice) + m_dlgRenice->setModal(true); + m_dlgRenice->show(); + } +- } +- else { ++ } else { ++ + //qDebug()<<"has entered"; + if (selectPid > -1) { + sysmonitor::process::Process info = ProcessMonitor::instance()->processList()->getProcessById(selectPid); +@@ -853,16 +848,13 @@ void ProcessTableView::changeProcPriority(int nice) + if (QFileInfo("/usr/bin/pkexec").exists()) {//sudo apt install policykit-1 + QProcess process; + process.execute(QString("pkexec --disable-internal-agent %1 %2 %3").arg("renice").arg(nice).arg(selectPid)); +- } +- else if (QFileInfo("/usr/bin/gksudo").exists()) {//sudo apt install gksu ++ } else if (QFileInfo("/usr/bin/gksudo").exists()) {//sudo apt install gksu + QProcess process; + process.execute(QString("gksudo \"%1 %2 %3\"").arg("renice").arg(nice).arg(selectPid)); +- } +- else if (QFileInfo("/usr/bin/gksu").exists()) {//sudo apt install gksu ++ } else if (QFileInfo("/usr/bin/gksu").exists()) {//sudo apt install gksu + QProcess process; + process.execute(QString("gksu \"%1 %2 %3\"").arg("renice").arg(nice).arg(selectPid)); +- } +- else { ++ } else { + // + } + } +diff --git a/src/process/processtableview.h b/src/process/processtableview.h +index 25d3879..108475f 100644 +--- a/src/process/processtableview.h ++++ b/src/process/processtableview.h +@@ -28,7 +28,6 @@ + #include "../controls/myactiongroupitem.h" + #include "../controls/myaction.h" + #include "../dialog/renicedialog.h" +-#include "process_oplimit.h" + + #include <QLabel> + #include <QTreeView> +@@ -251,8 +250,7 @@ private: + QString m_strFilter = "all"; + // change nice dialog + ReniceDialog *m_dlgRenice = nullptr; +- // check process permissions +- ProcessOpLimit *m_procOpLimit = nullptr; ++ + QShortcut *mApplyShortcut; + QPoint p{0,0}; + }; +diff --git a/src/process/processwidget.h b/src/process/processwidget.h +index 7f8a69f..cb9bc68 100644 +--- a/src/process/processwidget.h ++++ b/src/process/processwidget.h +@@ -8,7 +8,6 @@ + #include <QSettings> + #include <QButtonGroup> + +-#include "../controls/kgroupbutton.h" + #include "processtableview.h" + #include <kysdk/applications/ktabbar.h> + +diff --git a/src/process/processwndinfo.cpp b/src/process/processwndinfo.cpp +index 6437de8..b1859b4 100644 +--- a/src/process/processwndinfo.cpp ++++ b/src/process/processwndinfo.cpp +@@ -29,42 +29,6 @@ void ProcessWndInfo::updateWindowInfos() + } + } + +-bool ProcessWndInfo::acceptWindow(WId window) +-{ +- QFlags<NET::WindowTypeMask> ignoreList; +- ignoreList |= NET::DesktopMask; +- ignoreList |= NET::DockMask; +- ignoreList |= NET::SplashMask; +- ignoreList |= NET::ToolbarMask; +- ignoreList |= NET::MenuMask; +- ignoreList |= NET::PopupMenuMask; +- ignoreList |= NET::NotificationMask; +- +- KWindowInfo info(window, NET::WMWindowType | NET::WMState, NET::WM2TransientFor); +- if (!info.valid()) +- return false; +- +- if (NET::typeMatchesMask(info.windowType(NET::AllTypesMask), ignoreList)) +- return false; +- +- if (info.state() & NET::SkipTaskbar) +- return false; +- +- // WM_TRANSIENT_FOR hint not set - normal window +- WId transFor = info.transientFor(); +- if (transFor == 0 || transFor == window || transFor == (WId) QX11Info::appRootWindow()) +- return true; +- +- info = KWindowInfo(transFor, NET::WMWindowType); +- +- QFlags<NET::WindowTypeMask> normalFlag; +- normalFlag |= NET::NormalMask; +- normalFlag |= NET::DialogMask; +- normalFlag |= NET::UtilityMask; +- +- return !NET::typeMatchesMask(info.windowType(NET::AllTypesMask), normalFlag); +-} +- + QList<pid_t> ProcessWndInfo::getWindowPids() + { + return m_mapProcWndInfos.keys(); +diff --git a/src/process/processwndinfo.h b/src/process/processwndinfo.h +index 8432c6c..5107b8c 100644 +--- a/src/process/processwndinfo.h ++++ b/src/process/processwndinfo.h +@@ -22,7 +22,6 @@ public: + + public: + void updateWindowInfos(); +- bool acceptWindow(WId window); + QList<pid_t> getWindowPids(); + WId getWndIdByPid(pid_t pid); + QString getWndNameByPid(pid_t pid); +diff --git a/src/service/servicemanager.cpp b/src/service/servicemanager.cpp +index 3b618c8..6738af0 100644 +--- a/src/service/servicemanager.cpp ++++ b/src/service/servicemanager.cpp +@@ -14,7 +14,6 @@ + #include <QtDBus> + #include <QTimer> + #include <QThread> +-#include <QApplication> + + #include <sys/types.h> + #include <unistd.h> +diff --git a/src/service/systemd1serviceinterface.cpp b/src/service/systemd1serviceinterface.cpp +index 61fe9e2..f45acb0 100644 +--- a/src/service/systemd1serviceinterface.cpp ++++ b/src/service/systemd1serviceinterface.cpp +@@ -14,7 +14,10 @@ Systemd1ServiceInterface::Systemd1ServiceInterface(const QString &service, + + Systemd1ServiceInterface::~Systemd1ServiceInterface() + { +- m_dbusPropIFService->deleteLater(); ++ if (m_dbusPropIFService != nullptr) { ++ delete m_dbusPropIFService; ++ m_dbusPropIFService = nullptr; ++ } + } + + // 获取服务主进程id +diff --git a/src/src.pro b/src/src.pro +index b2a3502..b18cf24 100644 +--- a/src/src.pro ++++ b/src/src.pro +@@ -80,8 +80,6 @@ HEADERS += \ + filesystem/datacdrom.h \ + filesystem/filesysteminfoitem.h \ + filesystem/filesystemwidget.h \ +- imageutil.h \ +- kleftsideitem.h \ + kleftwidget.h \ + krightwidget.h \ + macro.h \ +@@ -123,7 +121,6 @@ HEADERS += \ + sysresource/netviewscrollarea.h \ + sysresource/netitemwidget.h \ + trayicon.h \ +- xatom-helper.h \ + util.h \ + desktopfileinfo.h \ + controls/mydialog.h \ +@@ -133,19 +130,16 @@ HEADERS += \ + controls/kitemdelegate.h \ + controls/kheaderview.h \ + controls/ktableview.h \ +- controls/kgroupbutton.h \ + filesystem/filesystemworker.h \ + filesystem/filesystemdata.h \ + filesystem/filesystemwatcher.h \ + dialog/renicedialog.h \ + dialog/procpropertiesdlg.h \ +- dialog/usmaboutdialog.h \ + process/processtableview.h \ + process/process_data.h \ + process/process_list.h \ + process/process_monitor.h \ + process/process_network.h \ +- process/process_oplimit.h \ + process/processtablemodel.h \ + process/processsortfilterproxymodel.h \ + style/usmproxystyle.h +@@ -160,8 +154,6 @@ SOURCES += \ + filesystem/datacdrom.cpp \ + filesystem/filesysteminfoitem.cpp \ + filesystem/filesystemwidget.cpp \ +- imageutil.cpp \ +- kleftsideitem.cpp \ + kleftwidget.cpp \ + krightwidget.cpp \ + mainwindow.cpp \ +@@ -201,7 +193,6 @@ SOURCES += \ + sysresource/netviewscrollarea.cpp \ + sysresource/netitemwidget.cpp \ + trayicon.cpp \ +- xatom-helper.cpp \ + main.cpp \ + util.cpp \ + desktopfileinfo.cpp \ +@@ -212,18 +203,15 @@ SOURCES += \ + controls/kitemdelegate.cpp \ + controls/kheaderview.cpp \ + controls/ktableview.cpp \ +- controls/kgroupbutton.cpp \ + filesystem/filesystemworker.cpp \ + filesystem/filesystemdata.cpp \ + filesystem/filesystemwatcher.cpp \ + dialog/renicedialog.cpp \ + dialog/procpropertiesdlg.cpp \ +- dialog/usmaboutdialog.cpp \ + process/processtableview.cpp \ + process/process_list.cpp \ + process/process_monitor.cpp \ + process/process_network.cpp \ +- process/process_oplimit.cpp \ + process/processtablemodel.cpp \ + process/processsortfilterproxymodel.cpp \ + style/usmproxystyle.cpp +diff --git a/src/util.cpp b/src/util.cpp +index 2808d4f..9f61a58 100644 +--- a/src/util.cpp ++++ b/src/util.cpp +@@ -20,7 +20,6 @@ + + #include "util.h" + +-#include <QApplication> + #include <QIcon> + #include <QDirIterator> + #include <QDebug> +@@ -28,75 +27,9 @@ + #include <glibtop/procstate.h> + #include <fstream> + #include <sstream> +-#include <QSvgRenderer> + #include <QProcess> + #include <kysdk/kysdk-base/kyutils.h> + +-bool loadSvg(const QString &fileName, const int size, QPixmap& pixmap) +-{ +- pixmap = pixmap.scaled(size, size); +- QSvgRenderer renderer(fileName); +- pixmap.fill(Qt::transparent); +- +- QPainter painter; +- painter.begin(&pixmap); +- renderer.render(&painter); +- painter.end(); +- +- return true; +-} +- +-QPixmap drawSymbolicColoredPixmap(const QPixmap &source) +-{ +- QColor gray(128,128,128); +- QColor standard (31,32,34); +- QImage img = source.toImage(); +- for (int x = 0; x < img.width(); x++) { +- for (int y = 0; y < img.height(); y++) { +- auto color = img.pixelColor(x, y); +- if (color.alpha() > 0) { +- if (qAbs(color.red()-gray.red())<20 && qAbs(color.green()-gray.green())<20 && qAbs(color.blue()-gray.blue())<20) { +- color.setRed(255); +- color.setGreen(255); +- color.setBlue(255); +- img.setPixelColor(x, y, color); +- } +- else if(qAbs(color.red()-standard.red())<20 && qAbs(color.green()-standard.green())<20 && qAbs(color.blue()-standard.blue())<20) +- { +- color.setRed(255); +- color.setGreen(255); +- color.setBlue(255); +- img.setPixelColor(x, y, color); +- } +- else +- { +- img.setPixelColor(x, y, color); +- } +- } +- } +- } +- return QPixmap::fromImage(img); +-} +- +-QPixmap drawSymbolicBlackColoredPixmap(const QPixmap &source) +-{ +- QImage img = source.toImage(); +- for (int x = 0; x < img.width(); x++) { +- for (int y = 0; y < img.height(); y++) { +- auto color = img.pixelColor(x, y); +- if (color.alpha() > 0) { +- if (qAbs(color.red())>=200 && qAbs(color.green())>=200 && qAbs(color.blue())>=200) { +- color.setRed(56); +- color.setGreen(56); +- color.setBlue(56); +- img.setPixelColor(x, y, color); +- } +- } +- } +- } +- return QPixmap::fromImage(img); +-} +- + std::string make_string(char *c_str) + { + if (!c_str) { +@@ -214,176 +147,6 @@ QString formatDurationForDisplay(unsigned centiseconds) + return formatTime; + } + +-std::string getDesktopFileAccordProcName(QString procName, QString cmdline) +-{ +- Q_UNUSED(cmdline); +- QDirIterator dir("/etc/xdg/autostart", QDirIterator::Subdirectories); +- std::string desktopFile; +- QString procname = procName.toLower(); +- procname.replace("_", "-"); +- QString processFilename = procname + ".desktop"; +- +- while(dir.hasNext()) { +- if (dir.fileInfo().suffix() == "desktop") { +- if (dir.fileName().toLower().contains(processFilename)) { +- desktopFile = dir.filePath().toStdString(); +-// qDebug()<<"---desktopFile---"<<desktopFile<<std::endl; +- break; +- } +- } +- dir.next(); +- } +- return desktopFile; +-} +- +-std::string getDesktopFileAccordProcNameApp(QString procName, QString cmdline) +-{ +- Q_UNUSED(cmdline); +- QDirIterator dir("/usr/share/applications", QDirIterator::Subdirectories); +- std::string desktopFile; +- // 去掉程序名称后缀 +- int nIndex = procName.lastIndexOf("."); +- if (nIndex != -1) { +- procName.truncate(nIndex); +- } +- QString procname = procName.toLower(); +- procname.replace("_", "-"); +- QString processFilename = procname + ".desktop"; +- +- while(dir.hasNext()) { +- if (dir.fileInfo().suffix() == "desktop") { +- if (dir.fileName().toLower() == processFilename +- || dir.fileName().toLower().contains("-"+processFilename)) { +- desktopFile = dir.filePath().toStdString(); +- break; +- } +- } +- dir.next(); +- } +- return desktopFile; +-} +- +-QPixmap getAppIconFromDesktopFile(std::string desktopFile, int iconSize) +-{ +- QIcon defaultExecutableIcon = QIcon::fromTheme("application-x-executable");//gnome-mine-application-x-executable +- if (defaultExecutableIcon.isNull()) { +- defaultExecutableIcon = QIcon("/usr/share/icons/ukui-icon-theme-default/48x48/mimetypes/application-x-executable.png"); +- if (defaultExecutableIcon.isNull()) +- defaultExecutableIcon = QIcon(":/res/autostart-default.png"); +- } +- +- QIcon icon; +- QString iconName; +- QString strDesktopFile = QString::fromStdString(desktopFile); +- if (!strDesktopFile.isEmpty()) { +- QFile file(strDesktopFile); +- if(file.open(QIODevice::ReadOnly | QIODevice::Text)) +- { +- QTextStream stream(&file); +- while(!stream.atEnd()) +- { +- iconName = stream.readLine(); +- +- if (iconName.startsWith("Icon=")) { +- iconName.remove(0,5); +- } +- else { +- continue; +- } +- +- if (iconName.contains("/")) { +- QFileInfo fileInfo(iconName); +- if (fileInfo.exists()) { +- icon = QIcon(iconName); +- break; +- } +- } +- else { +- icon = QIcon::fromTheme(iconName, defaultExecutableIcon); +- break; +- } +- } +- file.close(); +- } +- } +- +- qreal devicePixelRatio = 1;//qApp->devicePixelRatio(); +- QPixmap pixmap = icon.pixmap(iconSize * devicePixelRatio, iconSize * devicePixelRatio); +- // pixmap.setDevicePixelRatio(devicePixelRatio); +- +- return pixmap; +-} +- +-QString getAppIconPathFromDesktopFile(std::string desktopFile) +-{ +- QString strIconPath = ""; +- QString iconName; +- QString strDesktopFile = QString::fromStdString(desktopFile); +- if (!strDesktopFile.isEmpty()) { +- QFile file(strDesktopFile); +- if(file.open(QIODevice::ReadOnly | QIODevice::Text)) +- { +- QTextStream stream(&file); +- while(!stream.atEnd()) +- { +- iconName = stream.readLine(); +- +- if (iconName.startsWith("Icon=")) { +- iconName.remove(0,5); +- strIconPath = iconName; +- break; +- } +- else { +- continue; +- } +- } +- file.close(); +- } +- } +- return strIconPath; +-} +- +-QString getDisplayNameAccordProcName(QString procName, std::string desktopFile) +-{ +- if (desktopFile.size() == 0) { +- return procName; +- } +- +- QString iconName; +- QFile file(QString::fromStdString(desktopFile)); +- QString displayName = procName; +- if(file.open(QIODevice::ReadOnly | QIODevice::Text)) +- { +- QTextStream stream(&file); +- while(!stream.atEnd()) +- { +- QString lineContent = stream.readLine(); +- QString localNameFlag = QString("Name[%1]=").arg(QLocale::system().name()); +- QString nameFlag = "Name="; +- QString genericNameFlag = QString("GenericName[%1]=").arg(QLocale::system().name()); +- +- if (lineContent.startsWith(localNameFlag)) { +- displayName = lineContent.remove(0, localNameFlag.size()); +- break; +- } +- else if (lineContent.startsWith(genericNameFlag)) { +- displayName = lineContent.remove(0, genericNameFlag.size()); +- break; +- } +- else if (lineContent.startsWith(nameFlag)) { +- displayName = lineContent.remove(0, nameFlag.size()); +- continue; +- } +- else { +- continue; +- } +- } +- file.close(); +- } +- +- return displayName; +-} +- + QString formatProcessState(guint state) + { + QString status; +@@ -441,14 +204,6 @@ QString getNiceLevelWithPriority(int nice) + return QObject::tr("Very Low Priority"); + } + +-void setFontSize(QPainter &painter, int textSize) +-{ +- QFont font = painter.font() ; +- font.setPixelSize(textSize); +-// font.setPointSize(textSize); +- painter.setFont(font); +-} +- + QString formatUnitSize(double v, const char** orders, int nb_orders) + { + int order = 0; +diff --git a/src/util.h b/src/util.h +index 8c08e11..769c0b1 100644 +--- a/src/util.h ++++ b/src/util.h +@@ -37,18 +37,12 @@ + + using std::string; + +-std::string getDesktopFileAccordProcName(QString procName, QString cmdline); +-std::string getDesktopFileAccordProcNameApp(QString procName, QString cmdline); +-QPixmap getAppIconFromDesktopFile(std::string desktopFile, int iconSize = 24); +-QString getDisplayNameAccordProcName(QString procName, std::string desktopFile); +-QString getAppIconPathFromDesktopFile(std::string desktopFile); + std::string make_string(char *c_str); + QString formatProcessState(guint state); + QString getNiceLevel(int nice); + QString getNiceLevelWithPriority(int nice); + QString formatUnitSize(double v, const char** orders, int nb_orders); + QString formatByteCount(double v); +-void setFontSize(QPainter &painter, int textSize); + QString formatDurationForDisplay(unsigned centiseconds); + QString getDeviceMountedPointPath(const QString &line); + QString getFileContent(const QString &filePath); +@@ -56,13 +50,5 @@ QString getElidedText(QFont font, QString str, int MaxWidth); + QString getMiddleElidedText(QFont font, QString str, int MaxWidth); + QSet<QString> getFileContentsLineByLine(const QString &filePath); + +-bool loadSvg(const QString &fileName, const int size, QPixmap& pixmap); +- +-//图片反白 +-QPixmap drawSymbolicColoredPixmap(const QPixmap &source); +- +-//图片反黑 +-QPixmap drawSymbolicBlackColoredPixmap(const QPixmap &source); +- + // 获取应用程序版本 +-QString getUsmVersion(); +\ No newline at end of file ++QString getUsmVersion(); +diff --git a/src/xatom-helper.cpp b/src/xatom-helper.cpp +deleted file mode 100644 +index fefb6cd..0000000 +--- a/src/xatom-helper.cpp ++++ /dev/null +@@ -1,213 +0,0 @@ +-/* +- * Copyright (C) 2020 KylinSoft Co., Ltd. +- * +- * Authors: +- * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +-#include "xatom-helper.h" +- +-#include <limits.h> +- +-#include <QX11Info> +- +-#include <X11/Xlib.h> +-#include <X11/X.h> +-#include <X11/Xatom.h> +- +-static XAtomHelper *global_instance = nullptr; +- +-XAtomHelper *XAtomHelper::getInstance() +-{ +- if (!global_instance) +- global_instance = new XAtomHelper; +- return global_instance; +-} +- +-bool XAtomHelper::isFrameLessWindow(int winId) +-{ +- auto hints = getInstance()->getWindowMotifHint(winId); +- if (hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) { +- return true; +- } +- return false; +-} +- +-bool XAtomHelper::isWindowDecorateBorderOnly(int winId) +-{ +- return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId)); +-} +- +-bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint) +-{ +- bool isDeco = false; +- if (hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) { +- if (hint.decorations == MWM_DECOR_BORDER) +- isDeco = true; +- } +- return isDeco; +-} +- +-bool XAtomHelper::isUKUICsdSupported() +-{ +- // fixme: +- return false; +-} +- +-bool XAtomHelper::isUKUIDecorationWindow(int winId) +-{ +- if (m_ukuiDecorationAtion == None) +- return false; +- +- Atom type; +- int format; +- ulong nitems; +- ulong bytes_after; +- uchar *data; +- +- bool isUKUIDecoration = false; +- +- XGetWindowProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, +- 0, LONG_MAX, false, +- m_ukuiDecorationAtion, &type, +- &format, &nitems, +- &bytes_after, &data); +- +- if (type == m_ukuiDecorationAtion) { +- if (nitems == 1) { +- isUKUIDecoration = data[0]; +- } +- } +- +- return isUKUIDecoration; +-} +- +-UnityCorners XAtomHelper::getWindowBorderRadius(int winId) +-{ +- UnityCorners corners; +- +- Atom type; +- int format; +- ulong nitems; +- ulong bytes_after; +- uchar *data; +- +- if (m_unityBorderRadiusAtom != None) { +- XGetWindowProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, +- 0, LONG_MAX, false, +- XA_CARDINAL, &type, +- &format, &nitems, +- &bytes_after, &data); +- +- if (type == XA_CARDINAL) { +- if (nitems == 4) { +- corners.topLeft = static_cast<ulong>(data[0]); +- corners.topRight = static_cast<ulong>(data[1*sizeof (ulong)]); +- corners.bottomLeft = static_cast<ulong>(data[2*sizeof (ulong)]); +- corners.bottomRight = static_cast<ulong>(data[3*sizeof (ulong)]); +- } +- XFree(data); +- } +- } +- +- return corners; +-} +- +-void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data) +-{ +- if (m_unityBorderRadiusAtom == None) +- return; +- +- ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight}; +- +- XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, +- 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0])); +-} +- +-void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight) +-{ +- if (m_unityBorderRadiusAtom == None) +- return; +- +- ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight}; +- +- XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, +- 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0])); +-} +- +-void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set) +-{ +- if (m_ukuiDecorationAtion == None) +- return; +- +- XChangeProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &set, 1); +-} +- +-void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints) +-{ +- if (m_unityBorderRadiusAtom == None) +- return; +- +- XChangeProperty(QX11Info::display(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom, +- 32, XCB_PROP_MODE_REPLACE, (const unsigned char *)&hints, sizeof (MotifWmHints)/ sizeof (ulong)); +-} +- +-MotifWmHints XAtomHelper::getWindowMotifHint(int winId) +-{ +- MotifWmHints hints; +- +- if (m_unityBorderRadiusAtom == None) +- return hints; +- +- uchar *data; +- Atom type; +- int format; +- ulong nitems; +- ulong bytes_after; +- +- XGetWindowProperty(QX11Info::display(), winId, m_motifWMHintsAtom, +- 0, sizeof (MotifWmHints)/sizeof (long), false, AnyPropertyType, &type, +- &format, &nitems, &bytes_after, &data); +- +- if (type == None) { +- return hints; +- } else { +- hints = *(MotifWmHints *)data; +- XFree(data); +- } +- return hints; +-} +- +-XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent) +-{ +- if (!QX11Info::isPlatformX11()) +- return; +- +- m_motifWMHintsAtom = XInternAtom(QX11Info::display(), "_MOTIF_WM_HINTS", true); +- m_unityBorderRadiusAtom = XInternAtom(QX11Info::display(), "_UNITY_GTK_BORDER_RADIUS", false); +- m_ukuiDecorationAtion = XInternAtom(QX11Info::display(), "_KWIN_UKUI_DECORAION", false); +-} +- +-Atom XAtomHelper::registerUKUICsdNetWmSupportAtom() +-{ +- // fixme: +- return None; +-} +- +-void XAtomHelper::unregisterUKUICsdNetWmSupportAtom() +-{ +- // fixme: +-} +diff --git a/src/xatom-helper.h b/src/xatom-helper.h +deleted file mode 100644 +index 5460321..0000000 +--- a/src/xatom-helper.h ++++ /dev/null +@@ -1,107 +0,0 @@ +-/* +- * Copyright (C) 2020 KylinSoft Co., Ltd. +- * +- * Authors: +- * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation, either version 3 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program. If not, see <http://www.gnu.org/licenses/>. +- */ +- +- +-#ifndef XATOMHELPER_H +-#define XATOMHELPER_H +- +-#include <QObject> +- +-struct UnityCorners { +- ulong topLeft = 0; +- ulong topRight = 0; +- ulong bottomLeft = 0; +- ulong bottomRight = 0; +-}; +- +-typedef struct { +- ulong flags = 0; +- ulong functions = 0; +- ulong decorations = 0; +- long input_mode = 0; +- ulong status = 0; +-} MotifWmHints, MwmHints; +- +-#define MWM_HINTS_FUNCTIONS (1L << 0) +-#define MWM_HINTS_DECORATIONS (1L << 1) +-#define MWM_HINTS_INPUT_MODE (1L << 2) +-#define MWM_HINTS_STATUS (1L << 3) +- +-#define MWM_FUNC_ALL (1L << 0) +-#define MWM_FUNC_RESIZE (1L << 1) +-#define MWM_FUNC_MOVE (1L << 2) +-#define MWM_FUNC_MINIMIZE (1L << 3) +-#define MWM_FUNC_MAXIMIZE (1L << 4) +-#define MWM_FUNC_CLOSE (1L << 5) +- +-#define MWM_DECOR_ALL (1L << 0) +-#define MWM_DECOR_BORDER (1L << 1) +-#define MWM_DECOR_RESIZEH (1L << 2) +-#define MWM_DECOR_TITLE (1L << 3) +-#define MWM_DECOR_MENU (1L << 4) +-#define MWM_DECOR_MINIMIZE (1L << 5) +-#define MWM_DECOR_MAXIMIZE (1L << 6) +- +-#define MWM_INPUT_MODELESS 0 +-#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +-#define MWM_INPUT_SYSTEM_MODAL 2 +-#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +-#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL +- +-#define MWM_TEAROFF_WINDOW (1L<<0) +- +-namespace UKUI { +-class Decoration; +-} +- +-class XAtomHelper : public QObject +-{ +- friend class UKUI::Decoration; +- Q_OBJECT +-public: +- static XAtomHelper *getInstance(); +- +- static bool isFrameLessWindow(int winId); +- +- bool isWindowDecorateBorderOnly(int winId); +- bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint); +- bool isUKUICsdSupported(); +- bool isUKUIDecorationWindow(int winId); +- +- UnityCorners getWindowBorderRadius(int winId); +- void setWindowBorderRadius(int winId, const UnityCorners &data); +- void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight); +- void setUKUIDecoraiontHint(int winId, bool set = true); +- +- void setWindowMotifHint(int winId, const MotifWmHints &hints); +- MotifWmHints getWindowMotifHint(int winId); +- +-private: +- explicit XAtomHelper(QObject *parent = nullptr); +- +- ulong registerUKUICsdNetWmSupportAtom(); +- void unregisterUKUICsdNetWmSupportAtom(); +- +- ulong m_motifWMHintsAtom = 0L; +- ulong m_unityBorderRadiusAtom = 0L; +- ulong m_ukuiDecorationAtion = 0L; +-}; +- +-#endif // XATOMHELPER_H +diff --git a/tests/auto_test.sh b/tests/auto_test.sh +new file mode 100755 +index 0000000..29e7dc2 +--- /dev/null ++++ b/tests/auto_test.sh +@@ -0,0 +1,57 @@ ++#!/bin/bash ++ ++# 设置退出脚本当命令失败时 (非零退出状态) ++#set -e ++ ++# 函数:运行单元测试 ++run_unit_tests() { ++ ./unit_test_systemmonitor ++} ++ ++URL=$1 ++ ++# 上传 result.zip 到平台 ++upload_result() { ++ echo "current pwd : $(pwd)" ++ # 收集覆盖率信息 ++ lcov -d . -c -o r.info ++ ++ # 删除不需要的文件或路径 ++ lcov -r r.info "$(pwd)/unit_test_*" "$(pwd)/main.cpp" "$(pwd)/moc_*" "$(pwd)/../src/service/*.h" "$(pwd)/kt-test-utils/*" "/usr/include/*" "/opt/*" -o coverage.info ++ ++ # 生成html覆盖率报告 ++ genhtml "$(pwd)/coverage.info" -o result ++ ++ # 打包 ++ zip -r result.zip result ++ # 上传平台 ++ (curl --insecure -X POST -F "file=@/$(pwd)/result.zip" -F "package=ukui-system-monitor" -F "username=hesisheng" $URL) ++ echo "all parameter : $@ $0 $1" ++} ++ ++# 清除过程文件 ++clean_project() { ++ echo "clean moc* *.o" ++ rm moc_* *.o ++} ++ ++# 编译项目 ++echo "Compiling the project..." ++qmake && make ++ ++# 运行各个单元测试 ++echo "Running unit tests..." ++run_unit_tests ++ ++# 收集代码覆盖率数据,生成gcov文件 ++echo "Collecting coverage data..." ++find ./ -name '*.o' | xargs gcov --preserve-paths ++ ++# 上传到平台 ++echo "upload result.zip to platform" ++#upload_result ++ ++# 清理过程文件 ++#clean_project ++ ++echo "All tests have been run successfully, and coverage data has been collected." +diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp +new file mode 100644 +index 0000000..ff21dcd +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp +@@ -0,0 +1,58 @@ ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++#include "stub-shadow.h" ++ ++namespace stub_ext { ++ ++WrapperMap stub_wrappers; ++ ++Wrapper::Wrapper() ++{ ++ ++} ++ ++Wrapper::~Wrapper() ++{ ++ ++} ++ ++void freeWrapper(Wrapper *wrapper) ++{ ++ if (!wrapper) ++ return; ++ ++ for (auto iter = stub_wrappers.begin(); iter != stub_wrappers.end();) { ++ if (iter->second == wrapper) ++ iter = stub_wrappers.erase(iter); ++ else ++ ++iter; ++ } ++ ++ delete wrapper; ++} ++} ++ +diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h +new file mode 100644 +index 0000000..04e746e +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h +@@ -0,0 +1,171 @@ ++ ++#ifndef STUBSHADOW_H ++#define STUBSHADOW_H ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++#include <unordered_map> ++#include <assert.h> ++ ++namespace stub_ext { ++ ++#define LAMDA_FUNCTION_TYPE decltype(&Lamda::operator()) ++ ++class Wrapper ++{ ++public: ++ Wrapper(); ++ virtual ~Wrapper(); ++}; ++ ++typedef std::unordered_map<long, Wrapper* > WrapperMap; ++extern WrapperMap stub_wrappers; ++ ++template<class Lamda> ++class LamdaWrapper : public Wrapper ++{ ++public: ++ LamdaWrapper(Lamda func): Wrapper(),_func(func){} ++ ~LamdaWrapper(){} ++ Lamda _func; ++}; ++ ++template <typename Func> ++struct VFLocator ++{ ++ ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct VFLocator<Ret (Obj::*)(Args...)> ++{ ++ typedef Ret (*Func)(Obj*, Args...); ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct VFLocator<Ret (Obj::*)(Args...) const> ++{ ++ typedef Ret (*Func)(Obj*, Args...); ++}; ++ ++template <typename Func> ++struct LamdaCaller ++{ ++ ++}; ++ ++template <class Obj, typename Ret, typename... Args> ++struct LamdaCaller<Ret (Obj::*)(Args...) const> ++{ ++ template<class Lamda, typename ...OrgArgs> ++ static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args) ++ { ++ return wrapper->_func(std::forward<OrgArgs>(args)...); ++ } ++}; ++ ++template <class Obj, typename Ret> ++struct LamdaCaller<Ret (Obj::*)() const> ++{ ++ template<class Lamda, typename ...OrgArgs> ++ static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args) ++ { ++ return wrapper->_func(); ++ } ++}; ++ ++template<typename Func, class Lamda> ++struct FuncShadow ++{ ++ ++}; ++ ++template<typename Ret, typename... Args, class Lamda> ++struct FuncShadow<Ret (*)(Args...), Lamda> ++{ ++ typedef Ret (*Shadow)(Args...); ++ typedef Ret RetType; ++ ++ static Ret call(Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, args...); ++ } ++}; ++ ++template<typename Ret, class Obj,typename... Args, class Lamda> ++struct FuncShadow<Ret (Obj::*)(Args...), Lamda> ++{ ++ typedef Ret (*Shadow)(Obj *,Args...); ++ typedef Ret RetType; ++ static Ret call(Obj *obj, Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...); ++ } ++}; ++ ++ ++template<typename Ret, class Obj,typename... Args, class Lamda> ++struct FuncShadow<Ret (Obj::*)(Args...) const, Lamda> ++{ ++ typedef Ret (*Shadow)(Obj *,Args...); ++ typedef Ret RetType; ++ static Ret call(Obj *obj, Args ...args) ++ { ++ Shadow shadow = &call; ++ long id = (long)shadow; ++ auto iter = stub_wrappers.find(id); ++ assert(stub_wrappers.find(id) != stub_wrappers.end()); ++ LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second); ++ return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...); ++ } ++}; ++ ++template<typename Func, class Lamda> ++typename FuncShadow<Func, Lamda>::Shadow depictShadow(Wrapper **wrapper, Func func, Lamda lamda) ++{ ++ *wrapper = new LamdaWrapper<Lamda>(lamda); ++ typename FuncShadow<Func,Lamda>::Shadow shadow = &FuncShadow<Func,Lamda>::call; ++ long id = (long)shadow; ++ assert(stub_wrappers.find(id) == stub_wrappers.end()); ++ stub_wrappers.insert(std::make_pair(id,*wrapper)); ++ return shadow; ++} ++ ++void freeWrapper(Wrapper *wrapper); ++ ++} ++ ++#endif // STUBSHADOW_H +diff --git a/tests/kt-test-utils/cpp-stub-ext/stubext.h b/tests/kt-test-utils/cpp-stub-ext/stubext.h +new file mode 100644 +index 0000000..2a70a78 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub-ext/stubext.h +@@ -0,0 +1,129 @@ ++ ++#ifndef STUBEXT_H ++#define STUBEXT_H ++/* ++ * Author: Zhang Yu <clauszy@163.com> ++ * Maintainer: Zhang Yu <clauszy@163.com> ++ * ++ * MIT License ++ * ++ * Copyright (c) 2020 Zhang Yu ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a copy ++ * of this software and associated documentation files (the "Software"), to deal ++ * in the Software without restriction, including without limitation the rights ++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ * copies of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in all ++ * copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++*/ ++//需修改Stub的私用成员函数和成员变量为保护类型 ++#include "stub.h" ++ ++#include "stub-shadow.h" ++ ++#ifdef DEBUG_STUB_INVOKE ++// use to make sure the stub function is invoked. ++# define __DBG_STUB_INVOKE__ printf("stub at %s:%d is invoked.\n", __FILE__, __LINE__); ++#else ++# define __DBG_STUB_INVOKE__ ++#endif ++ ++#define VADDR(CLASS_NAME, MEMBER_NAME) (typename stub_ext::VFLocator<decltype(&CLASS_NAME::MEMBER_NAME)>::Func)(&CLASS_NAME::MEMBER_NAME) ++ ++namespace stub_ext { ++ ++class StubExt : public Stub ++{ ++public: ++ StubExt() ++ : Stub() { } ++ ++ template<typename T, class Lamda> ++ bool set_lamda(T addr, Lamda lamda) ++ { ++ char *fn = addrof(addr); ++ if (m_result.find(fn) != m_result.end()) ++ reset(addr); ++ ++ Wrapper *wrapper = nullptr; ++ auto addr_stub = depictShadow(&wrapper, addr, lamda); ++ if (set(addr, addr_stub)) { ++ m_wrappers.insert(std::make_pair(fn, wrapper)); ++ return true; ++ } else { ++ freeWrapper(wrapper); ++ } ++ return false; ++ } ++ ++ template<typename T> ++ void reset(T addr) ++ { ++ Stub::reset(addr); ++ char *fn = addrof(addr); ++ auto iter = m_wrappers.find(fn); ++ if (iter != m_wrappers.end()) { ++ freeWrapper(iter->second); ++ m_wrappers.erase(iter); ++ } ++ } ++ ++ ~StubExt() ++ { ++ clear(); ++ } ++ ++ void clear() override ++ { ++ Stub::clear(); ++ for (auto iter = m_wrappers.begin(); iter != m_wrappers.end(); ++iter) { ++ freeWrapper(iter->second); ++ } ++ m_wrappers.clear(); ++ } ++ ++ template<class T> ++ static void *get_ctor_addr(bool start = true) ++ { ++ // the start vairable must be true, or the compiler will optimize out. ++ if (start) goto Start; ++ Call_Constructor: ++ // This line of code will not be executed. ++ // The purpose of the code is to allow the compiler to generate the assembly code that calls the constructor. ++ T(); ++ Start: ++ // The address of the line of code T() obtained by assembly ++ char *p = (char *)&&Call_Constructor; // https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html ++ // CALL rel32 ++ void *ret = 0; ++ char pos; ++ char call = 0xe8; ++ do { ++ pos = *p; ++ if (pos == call) { ++ ret = p + 5 + (*(int *)(p + 1)); ++ } ++ ++ } while (!ret && (++p)); ++ ++ return ret; ++ } ++ ++protected: ++ std::map<char *, Wrapper *> m_wrappers; ++}; ++ ++} ++ ++#endif // STUBEXT_H +diff --git a/tests/kt-test-utils/cpp-stub/addr_any.h b/tests/kt-test-utils/cpp-stub/addr_any.h +new file mode 100644 +index 0000000..66d4ea3 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/addr_any.h +@@ -0,0 +1,298 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#ifndef __ADDR_ANY_H__ ++#define __ADDR_ANY_H__ ++ ++ ++//linux ++#include <regex.h> ++#include <cxxabi.h> ++//c ++#include <cinttypes> ++#include <cstdio> ++#include <cstdlib> ++ ++//c++ ++#include <string> ++#include <map> ++//project ++#include "elfio.hpp" ++ ++ ++ ++class AddrAny ++{ ++public: ++ AddrAny() ++ { ++ m_init = get_exe_pathname(m_fullname); ++ m_baseaddr = 0; ++ } ++ AddrAny(std::string libname) ++ { ++ m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr); ++ } ++ ++ int get_local_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result); ++ } ++ int get_global_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result); ++ } ++ int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result); ++ } ++ ++ int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result); ++ } ++ int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result); ++ } ++ ++private: ++ bool demangle(std::string& s, std::string& name) { ++ int status; ++ char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status); ++ if (status != 0) ++ { ++ switch(status) ++ { ++ case -1: name = "memory allocation error"; break; ++ case -2: name = "invalid name given"; break; ++ case -3: name = "internal error: __cxa_demangle: invalid argument"; break; ++ default: name = "unknown error occured"; break; ++ } ++ return false; ++ } ++ name = pname; ++ free(pname); ++ return true; ++ } ++ bool get_exe_pathname( std::string& name) ++ { ++ char line[512]; ++ FILE *fp; ++ uintptr_t base_addr; ++ char perm[5]; ++ unsigned long offset; ++ int pathname_pos; ++ char *pathname; ++ size_t pathname_len; ++ int match = 0; ++ ++ if(NULL == (fp = fopen("/proc/self/maps", "r"))) ++ { ++ return false; ++ } ++ ++ while(fgets(line, sizeof(line), fp)) ++ { ++ if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; ++ ++ if(0 != offset) continue; ++ ++ //get pathname ++ while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) ++ pathname_pos += 1; ++ if(pathname_pos >= (int)(sizeof(line) - 1)) continue; ++ pathname = line + pathname_pos; ++ pathname_len = strlen(pathname); ++ if(0 == pathname_len) continue; ++ if(pathname[pathname_len - 1] == '\n') ++ { ++ pathname[pathname_len - 1] = '\0'; ++ pathname_len -= 1; ++ } ++ if(0 == pathname_len) continue; ++ if('[' == pathname[0]) continue; ++ ++ name = pathname; ++ match = 1; ++ break; ++ ++ } ++ fclose(fp); ++ ++ if(0 == match) ++ { ++ return false; ++ } ++ else ++ { ++ return true; ++ } ++ ++ } ++ ++ bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr) ++ { ++ char line[512]; ++ FILE *fp; ++ uintptr_t base_addr; ++ char perm[5]; ++ unsigned long offset; ++ int pathname_pos; ++ char *pathname; ++ size_t pathname_len; ++ int match; ++ regex_t pathname_regex; ++ ++ regcomp(&pathname_regex, pathname_regex_str.c_str(), 0); ++ ++ if(NULL == (fp = fopen("/proc/self/maps", "r"))) ++ { ++ return false; ++ } ++ ++ while(fgets(line, sizeof(line), fp)) ++ { ++ if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; ++ ++ //check permission ++ if(perm[0] != 'r') continue; ++ if(perm[3] != 'p') continue; //do not touch the shared memory ++ ++ //check offset ++ // ++ //We are trying to find ELF header in memory. ++ //It can only be found at the beginning of a mapped memory regions ++ //whose offset is 0. ++ if(0 != offset) continue; ++ ++ //get pathname ++ while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) ++ pathname_pos += 1; ++ if(pathname_pos >= (int)(sizeof(line) - 1)) continue; ++ pathname = line + pathname_pos; ++ pathname_len = strlen(pathname); ++ if(0 == pathname_len) continue; ++ if(pathname[pathname_len - 1] == '\n') ++ { ++ pathname[pathname_len - 1] = '\0'; ++ pathname_len -= 1; ++ } ++ if(0 == pathname_len) continue; ++ if('[' == pathname[0]) continue; ++ ++ //check pathname ++ //if we need to hook this elf? ++ match = 0; ++ if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0)) ++ { ++ match = 1; ++ name = pathname; ++ addr = (unsigned long)base_addr; ++ break; ++ } ++ if(0 == match) continue; ++ ++ } ++ fclose(fp); ++ if(0 == match) ++ { ++ return false; ++ } ++ else ++ { ++ return true; ++ } ++ ++ } ++ ++ int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map<std::string,void*>& result) ++ { ++ // Create an elfio reader ++ ELFIO::elfio reader; ++ int count = 0; ++ regex_t pathname_regex; ++ ++ if(!m_init) ++ { ++ return -1; ++ } ++ ++ regcomp(&pathname_regex, func_name_regex_str.c_str(), 0); ++ // Load ELF data ++ if(!reader.load(m_fullname.c_str())) ++ { ++ return -1; ++ } ++ ++ ELFIO::Elf_Half sec_num = reader.sections.size(); ++ for(int i = 0; i < sec_num; ++i) ++ { ++ ELFIO::section* psec = reader.sections[i]; ++ // Check section type ++ if(psec->get_type() == ttype) ++ { ++ const ELFIO::symbol_section_accessor symbols( reader, psec ); ++ for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) ++ { ++ std::string name; ++ std::string name_mangle; ++ ELFIO::Elf64_Addr value; ++ ELFIO::Elf_Xword size; ++ unsigned char bind; ++ unsigned char type; ++ ELFIO::Elf_Half section_index; ++ unsigned char other; ++ ++ // Read symbol properties ++ symbols.get_symbol( j, name, value, size, bind, type, section_index, other ); ++ if(type == STT_FUNC && bind == stype) ++ { ++ bool ret = demangle(name,name_mangle); ++ if(ret == true) ++ { ++ if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0)) ++ { ++ result.insert ( std::pair<std::string,void *>(name_mangle,(void*)(value + m_baseaddr))); ++ count++; ++ } ++ } ++ else ++ { ++ if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0)) ++ { ++ result.insert ( std::pair<std::string,void *>(name,(void*)(value + m_baseaddr))); ++ count++; ++ } ++ } ++ } ++ } ++ break; ++ } ++ } ++ ++ return count; ++ } ++private: ++ bool m_init; ++ std::string m_name; ++ std::string m_fullname; ++ unsigned long m_baseaddr; ++ ++}; ++#endif +diff --git a/tests/kt-test-utils/cpp-stub/addr_pri.h b/tests/kt-test-utils/cpp-stub/addr_pri.h +new file mode 100644 +index 0000000..2bfb27b +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/addr_pri.h +@@ -0,0 +1,195 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#ifndef __ADDR_PRI_H__ ++#define __ADDR_PRI_H__ ++ ++ ++#include <utility> ++#include <type_traits> ++ ++ ++ ++//base on C++11 ++ ++/********************************************************** ++ access private function ++**********************************************************/ ++ ++ ++namespace std { ++ template <bool B, class T = void> ++ using enable_if_t = typename enable_if<B, T>::type; ++ template <class T> ++ using remove_reference_t = typename remove_reference<T>::type; ++} // std ++ ++// Unnamed namespace is used to avoid duplicate symbols if the macros are used ++namespace { ++ namespace private_access_detail { ++ ++ // @tparam TagType, used to declare different "get" funciton overloads for ++ // different members/statics ++ template <typename PtrType, PtrType PtrValue, typename TagType> ++ struct private_access { ++ // Normal lookup cannot find in-class defined (inline) friend functions. ++ friend PtrType get(TagType) { return PtrValue; } ++ }; ++ ++ } // namespace private_access_detail ++} // namespace ++ ++// Used macro naming conventions: ++// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all ++// macro here has this prefix. ++// All implementation macro, which are not meant to be used directly have the ++// PRIVATE_ACCESS_DETAIL prefix. ++// Some macros have the ABCD_IMPL form, which means they contain the ++// implementation details for the specific ABCD macro. ++ ++#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y ++#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) ++ ++// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of ++// members, or it can be "*" in case of statics. ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \ ++ PtrTypeKind) \ ++ namespace { \ ++ namespace private_access_detail { \ ++ /* Tag type, used to declare different get funcitons for different \ ++ * members \ ++ */ \ ++ struct Tag {}; \ ++ /* Explicit instantiation */ \ ++ template struct private_access<decltype(&Class::Name), &Class::Name, \ ++ Tag>; \ ++ /* We can build the PtrType only with two aliases */ \ ++ /* E.g. using PtrType = int(int) *; would be illformed */ \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \ ++ /* Declare the friend function, now it is visible in namespace scope. \ ++ * Note, \ ++ * we could declare it inside the Tag type too, in that case ADL would \ ++ * find \ ++ * the declaration. By choosing to declare it here, the Tag type remains \ ++ * a \ ++ * simple tag type, it has no other responsibilities. */ \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ ++ namespace { \ ++ namespace access_private_field { \ ++ Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \ ++ Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \ ++ /* The following usings are here to avoid duplicate const qualifier \ ++ * warnings \ ++ */ \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \ ++ using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \ ++ const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\ ++ return t.*get(private_access_detail::Tag{}); \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \ ++ namespace { \ ++ namespace call_private_fun { \ ++ /* We do perfect forwarding, but we want to restrict the overload set \ ++ * only for objects which have the type Class. */ \ ++ template <typename Obj, \ ++ std::enable_if_t<std::is_same<std::remove_reference_t<Obj>, \ ++ Class>::value> * = nullptr, \ ++ typename... Args> \ ++ auto Class##Name(Obj &&o, Args &&... args) -> decltype( \ ++ (std::forward<Obj>(o).* \ ++ get(private_access_detail::Tag{}))(std::forward<Args>(args)...)) { \ ++ return (std::forward<Obj>(o).*get(private_access_detail::Tag{}))( \ ++ std::forward<Args>(args)...); \ ++ } \ ++ } \ ++ namespace get_private_fun { \ ++ auto Class##Name() -> decltype( \ ++ get(private_access_detail::Tag{})) { \ ++ return (get(private_access_detail::Tag{})); \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \ ++ Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ ++ namespace { \ ++ namespace access_private_static_field { \ ++ namespace Class { \ ++ Type &Class##Name() { return *get(private_access_detail::Tag{}); } \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \ ++ Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \ ++ namespace { \ ++ namespace call_private_static_fun { \ ++ namespace Class { \ ++ template <typename... Args> \ ++ auto Class##Name(Args &&... args) -> decltype( \ ++ get(private_access_detail::Tag{})(std::forward<Args>(args)...)) { \ ++ return get(private_access_detail::Tag{})( \ ++ std::forward<Args>(args)...); \ ++ } \ ++ } \ ++ } \ ++ namespace get_private_static_fun { \ ++ namespace Class { \ ++ auto Class##Name() -> decltype(get(private_access_detail::Tag{})) { \ ++ return get(private_access_detail::Tag{}); \ ++ } \ ++ } \ ++ } \ ++ } ++ ++#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \ ++ PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__) ++ ++#define ACCESS_PRIVATE_FIELD(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ ++ Class, Type, Name) ++ ++#define ACCESS_PRIVATE_FUN(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \ ++ Class, Type, Name) ++ ++#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \ ++ Type Class::Name; \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \ ++ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) ++ ++#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \ ++ PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \ ++ PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name) ++ ++#endif +diff --git a/tests/kt-test-utils/cpp-stub/elfio.hpp b/tests/kt-test-utils/cpp-stub/elfio.hpp +new file mode 100644 +index 0000000..dd5c9ae +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/elfio.hpp +@@ -0,0 +1,4888 @@ ++ ++/*** Start of inlined file: elfio_dump.hpp ***/ ++#ifndef ELFIO_DUMP_HPP ++#define ELFIO_DUMP_HPP ++ ++#include <algorithm> ++#include <string> ++#include <ostream> ++#include <sstream> ++#include <iomanip> ++ ++/*** Start of inlined file: elfio.hpp ***/ ++#ifndef ELFIO_HPP ++#define ELFIO_HPP ++ ++#ifdef _MSC_VER ++#pragma warning( push ) ++#pragma warning( disable : 4996 ) ++#pragma warning( disable : 4355 ) ++#pragma warning( disable : 4244 ) ++#endif ++ ++#include <string> ++#include <iostream> ++#include <fstream> ++#include <functional> ++#include <algorithm> ++#include <vector> ++#include <deque> ++#include <iterator> ++ ++ ++/*** Start of inlined file: elf_types.hpp ***/ ++#ifndef ELFTYPES_H ++#define ELFTYPES_H ++ ++#ifndef ELFIO_NO_OWN_TYPES ++#if !defined( ELFIO_NO_CSTDINT ) && !defined( ELFIO_NO_INTTYPES ) ++#include <stdint.h> ++#else ++typedef unsigned char uint8_t; ++typedef signed char int8_t; ++typedef unsigned short uint16_t; ++typedef signed short int16_t; ++#ifdef _MSC_VER ++typedef unsigned __int32 uint32_t; ++typedef signed __int32 int32_t; ++typedef unsigned __int64 uint64_t; ++typedef signed __int64 int64_t; ++#else ++typedef unsigned int uint32_t; ++typedef signed int int32_t; ++typedef unsigned long long uint64_t; ++typedef signed long long int64_t; ++#endif // _MSC_VER ++#endif // ELFIO_NO_CSTDINT ++#endif // ELFIO_NO_OWN_TYPES ++ ++namespace ELFIO { ++ ++// Attention! Platform depended definitions. ++typedef uint16_t Elf_Half; ++typedef uint32_t Elf_Word; ++typedef int32_t Elf_Sword; ++typedef uint64_t Elf_Xword; ++typedef int64_t Elf_Sxword; ++ ++typedef uint32_t Elf32_Addr; ++typedef uint32_t Elf32_Off; ++typedef uint64_t Elf64_Addr; ++typedef uint64_t Elf64_Off; ++ ++#define Elf32_Half Elf_Half ++#define Elf64_Half Elf_Half ++#define Elf32_Word Elf_Word ++#define Elf64_Word Elf_Word ++#define Elf32_Sword Elf_Sword ++#define Elf64_Sword Elf_Sword ++ ++/////////////////////// ++// ELF Header Constants ++ ++// File type ++#define ET_NONE 0 ++#define ET_REL 1 ++#define ET_EXEC 2 ++#define ET_DYN 3 ++#define ET_CORE 4 ++#define ET_LOOS 0xFE00 ++#define ET_HIOS 0xFEFF ++#define ET_LOPROC 0xFF00 ++#define ET_HIPROC 0xFFFF ++ ++#define EM_NONE 0 // No machine ++#define EM_M32 1 // AT&T WE 32100 ++#define EM_SPARC 2 // SUN SPARC ++#define EM_386 3 // Intel 80386 ++#define EM_68K 4 // Motorola m68k family ++#define EM_88K 5 // Motorola m88k family ++#define EM_486 6 // Intel 80486// Reserved for future use ++#define EM_860 7 // Intel 80860 ++#define EM_MIPS 8 // MIPS R3000 (officially, big-endian only) ++#define EM_S370 9 // IBM System/370 ++#define EM_MIPS_RS3_LE \ ++ 10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated ++#define EM_res011 11 // Reserved ++#define EM_res012 12 // Reserved ++#define EM_res013 13 // Reserved ++#define EM_res014 14 // Reserved ++#define EM_PARISC 15 // HPPA ++#define EM_res016 16 // Reserved ++#define EM_VPP550 17 // Fujitsu VPP500 ++#define EM_SPARC32PLUS 18 // Sun's "v8plus" ++#define EM_960 19 // Intel 80960 ++#define EM_PPC 20 // PowerPC ++#define EM_PPC64 21 // 64-bit PowerPC ++#define EM_S390 22 // IBM S/390 ++#define EM_SPU 23 // Sony/Toshiba/IBM SPU ++#define EM_res024 24 // Reserved ++#define EM_res025 25 // Reserved ++#define EM_res026 26 // Reserved ++#define EM_res027 27 // Reserved ++#define EM_res028 28 // Reserved ++#define EM_res029 29 // Reserved ++#define EM_res030 30 // Reserved ++#define EM_res031 31 // Reserved ++#define EM_res032 32 // Reserved ++#define EM_res033 33 // Reserved ++#define EM_res034 34 // Reserved ++#define EM_res035 35 // Reserved ++#define EM_V800 36 // NEC V800 series ++#define EM_FR20 37 // Fujitsu FR20 ++#define EM_RH32 38 // TRW RH32 ++#define EM_MCORE 39 // Motorola M*Core // May also be taken by Fujitsu MMA ++#define EM_RCE 39 // Old name for MCore ++#define EM_ARM 40 // ARM ++#define EM_OLD_ALPHA 41 // Digital Alpha ++#define EM_SH 42 // Renesas (formerly Hitachi) / SuperH SH ++#define EM_SPARCV9 43 // SPARC v9 64-bit ++#define EM_TRICORE 44 // Siemens Tricore embedded processor ++#define EM_ARC 45 // ARC Cores ++#define EM_H8_300 46 // Renesas (formerly Hitachi) H8/300 ++#define EM_H8_300H 47 // Renesas (formerly Hitachi) H8/300H ++#define EM_H8S 48 // Renesas (formerly Hitachi) H8S ++#define EM_H8_500 49 // Renesas (formerly Hitachi) H8/500 ++#define EM_IA_64 50 // Intel IA-64 Processor ++#define EM_MIPS_X 51 // Stanford MIPS-X ++#define EM_COLDFIRE 52 // Motorola Coldfire ++#define EM_68HC12 53 // Motorola M68HC12 ++#define EM_MMA 54 // Fujitsu Multimedia Accelerator ++#define EM_PCP 55 // Siemens PCP ++#define EM_NCPU 56 // Sony nCPU embedded RISC processor ++#define EM_NDR1 57 // Denso NDR1 microprocesspr ++#define EM_STARCORE 58 // Motorola Star*Core processor ++#define EM_ME16 59 // Toyota ME16 processor ++#define EM_ST100 60 // STMicroelectronics ST100 processor ++#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor ++#define EM_X86_64 62 // Advanced Micro Devices X86-64 processor ++#define EM_PDSP 63 // Sony DSP Processor ++#define EM_PDP10 64 // Digital Equipment Corp. PDP-10 ++#define EM_PDP11 65 // Digital Equipment Corp. PDP-11 ++#define EM_FX66 66 // Siemens FX66 microcontroller ++#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller ++#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller ++#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller ++#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller ++#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller ++#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller ++#define EM_SVX 73 // Silicon Graphics SVx ++#define EM_ST19 74 // STMicroelectronics ST19 8-bit cpu ++#define EM_VAX 75 // Digital VAX ++#define EM_CRIS 76 // Axis Communications 32-bit embedded processor ++#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded cpu ++#define EM_FIREPATH 78 // Element 14 64-bit DSP processor ++#define EM_ZSP 79 // LSI Logic's 16-bit DSP processor ++#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor ++#define EM_HUANY 81 // Harvard's machine-independent format ++#define EM_PRISM 82 // SiTera Prism ++#define EM_AVR 83 // Atmel AVR 8-bit microcontroller ++#define EM_FR30 84 // Fujitsu FR30 ++#define EM_D10V 85 // Mitsubishi D10V ++#define EM_D30V 86 // Mitsubishi D30V ++#define EM_V850 87 // NEC v850 ++#define EM_M32R 88 // Renesas M32R (formerly Mitsubishi M32R) ++#define EM_MN10300 89 // Matsushita MN10300 ++#define EM_MN10200 90 // Matsushita MN10200 ++#define EM_PJ 91 // picoJava ++#define EM_OPENRISC 92 // OpenRISC 32-bit embedded processor ++#define EM_ARC_A5 93 // ARC Cores Tangent-A5 ++#define EM_XTENSA 94 // Tensilica Xtensa Architecture ++#define EM_VIDEOCORE 95 // Alphamosaic VideoCore processor ++#define EM_TMM_GPP 96 // Thompson Multimedia General Purpose Processor ++#define EM_NS32K 97 // National Semiconductor 32000 series ++#define EM_TPC 98 // Tenor Network TPC processor ++#define EM_SNP1K 99 // Trebia SNP 1000 processor ++#define EM_ST200 100 // STMicroelectronics ST200 microcontroller ++#define EM_IP2K 101 // Ubicom IP2022 micro controller ++#define EM_MAX 102 // MAX Processor ++#define EM_CR 103 // National Semiconductor CompactRISC ++#define EM_F2MC16 104 // Fujitsu F2MC16 ++#define EM_MSP430 105 // TI msp430 micro controller ++#define EM_BLACKFIN 106 // ADI Blackfin ++#define EM_SE_C33 107 // S1C33 Family of Seiko Epson processors ++#define EM_SEP 108 // Sharp embedded microprocessor ++#define EM_ARCA 109 // Arca RISC Microprocessor ++#define EM_UNICORE \ ++ 110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University ++#define EM_EXCESS 111 // eXcess: 16/32/64-bit configurable embedded CPU ++#define EM_DXP 112 // Icera Semiconductor Inc. Deep Execution Processor ++#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor ++#define EM_CRX 114 // National Semiconductor CRX ++#define EM_XGATE 115 // Motorola XGATE embedded processor ++#define EM_C166 116 // Infineon C16x/XC16x processor ++#define EM_M16C 117 // Renesas M16C series microprocessors ++#define EM_DSPIC30F \ ++ 118 // Microchip Technology dsPIC30F Digital Signal Controller ++#define EM_CE 119 // Freescale Communication Engine RISC core ++#define EM_M32C 120 // Renesas M32C series microprocessors ++#define EM_res121 121 // Reserved ++#define EM_res122 122 // Reserved ++#define EM_res123 123 // Reserved ++#define EM_res124 124 // Reserved ++#define EM_res125 125 // Reserved ++#define EM_res126 126 // Reserved ++#define EM_res127 127 // Reserved ++#define EM_res128 128 // Reserved ++#define EM_res129 129 // Reserved ++#define EM_res130 130 // Reserved ++#define EM_TSK3000 131 // Altium TSK3000 core ++#define EM_RS08 132 // Freescale RS08 embedded processor ++#define EM_res133 133 // Reserved ++#define EM_ECOG2 134 // Cyan Technology eCOG2 microprocessor ++#define EM_SCORE 135 // Sunplus Score ++#define EM_SCORE7 135 // Sunplus S+core7 RISC processor ++#define EM_DSP24 136 // New Japan Radio (NJR) 24-bit DSP Processor ++#define EM_VIDEOCORE3 137 // Broadcom VideoCore III processor ++#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture ++#define EM_SE_C17 139 // Seiko Epson C17 family ++#define EM_TI_C6000 140 // Texas Instruments TMS320C6000 DSP family ++#define EM_TI_C2000 141 // Texas Instruments TMS320C2000 DSP family ++#define EM_TI_C5500 142 // Texas Instruments TMS320C55x DSP family ++#define EM_res143 143 // Reserved ++#define EM_res144 144 // Reserved ++#define EM_res145 145 // Reserved ++#define EM_res146 146 // Reserved ++#define EM_res147 147 // Reserved ++#define EM_res148 148 // Reserved ++#define EM_res149 149 // Reserved ++#define EM_res150 150 // Reserved ++#define EM_res151 151 // Reserved ++#define EM_res152 152 // Reserved ++#define EM_res153 153 // Reserved ++#define EM_res154 154 // Reserved ++#define EM_res155 155 // Reserved ++#define EM_res156 156 // Reserved ++#define EM_res157 157 // Reserved ++#define EM_res158 158 // Reserved ++#define EM_res159 159 // Reserved ++#define EM_MMDSP_PLUS 160 // STMicroelectronics 64bit VLIW Data Signal Processor ++#define EM_CYPRESS_M8C 161 // Cypress M8C microprocessor ++#define EM_R32C 162 // Renesas R32C series microprocessors ++#define EM_TRIMEDIA 163 // NXP Semiconductors TriMedia architecture family ++#define EM_QDSP6 164 // QUALCOMM DSP6 Processor ++#define EM_8051 165 // Intel 8051 and variants ++#define EM_STXP7X 166 // STMicroelectronics STxP7x family ++#define EM_NDS32 \ ++ 167 // Andes Technology compact code size embedded RISC processor family ++#define EM_ECOG1 168 // Cyan Technology eCOG1X family ++#define EM_ECOG1X 168 // Cyan Technology eCOG1X family ++#define EM_MAXQ30 169 // Dallas Semiconductor MAXQ30 Core Micro-controllers ++#define EM_XIMO16 170 // New Japan Radio (NJR) 16-bit DSP Processor ++#define EM_MANIK 171 // M2000 Reconfigurable RISC Microprocessor ++#define EM_CRAYNV2 172 // Cray Inc. NV2 vector architecture ++#define EM_RX 173 // Renesas RX family ++#define EM_METAG 174 // Imagination Technologies META processor architecture ++#define EM_MCST_ELBRUS 175 // MCST Elbrus general purpose hardware architecture ++#define EM_ECOG16 176 // Cyan Technology eCOG16 family ++#define EM_CR16 177 // National Semiconductor CompactRISC 16-bit processor ++#define EM_ETPU 178 // Freescale Extended Time Processing Unit ++#define EM_SLE9X 179 // Infineon Technologies SLE9X core ++#define EM_L1OM 180 // Intel L1OM ++#define EM_INTEL181 181 // Reserved by Intel ++#define EM_INTEL182 182 // Reserved by Intel ++#define EM_res183 183 // Reserved by ARM ++#define EM_res184 184 // Reserved by ARM ++#define EM_AVR32 185 // Atmel Corporation 32-bit microprocessor family ++#define EM_STM8 186 // STMicroeletronics STM8 8-bit microcontroller ++#define EM_TILE64 187 // Tilera TILE64 multicore architecture family ++#define EM_TILEPRO 188 // Tilera TILEPro multicore architecture family ++#define EM_MICROBLAZE 189 // Xilinx MicroBlaze 32-bit RISC soft processor core ++#define EM_CUDA 190 // NVIDIA CUDA architecture ++#define EM_TILEGX 191 // Tilera TILE-Gx multicore architecture family ++#define EM_CLOUDSHIELD 192 // CloudShield architecture family ++#define EM_COREA_1ST 193 // KIPO-KAIST Core-A 1st generation processor family ++#define EM_COREA_2ND 194 // KIPO-KAIST Core-A 2nd generation processor family ++#define EM_ARC_COMPACT2 195 // Synopsys ARCompact V2 ++#define EM_OPEN8 196 // Open8 8-bit RISC soft processor core ++#define EM_RL78 197 // Renesas RL78 family ++#define EM_VIDEOCORE5 198 // Broadcom VideoCore V processor ++#define EM_78KOR 199 // Renesas 78KOR family ++#define EM_56800EX 200 // Freescale 56800EX Digital Signal Controller (DSC) ++#define EM_BA1 201 // Beyond BA1 CPU architecture ++#define EM_BA2 202 // Beyond BA2 CPU architecture ++#define EM_XCORE 203 // XMOS xCORE processor family ++#define EM_MCHP_PIC 204 // Microchip 8-bit PIC(r) family ++#define EM_INTEL205 205 // Reserved by Intel ++#define EM_INTEL206 206 // Reserved by Intel ++#define EM_INTEL207 207 // Reserved by Intel ++#define EM_INTEL208 208 // Reserved by Intel ++#define EM_INTEL209 209 // Reserved by Intel ++#define EM_KM32 210 // KM211 KM32 32-bit processor ++#define EM_KMX32 211 // KM211 KMX32 32-bit processor ++#define EM_KMX16 212 // KM211 KMX16 16-bit processor ++#define EM_KMX8 213 // KM211 KMX8 8-bit processor ++#define EM_KVARC 214 // KM211 KVARC processor ++#define EM_CDP 215 // Paneve CDP architecture family ++#define EM_COGE 216 // Cognitive Smart Memory Processor ++#define EM_COOL 217 // iCelero CoolEngine ++#define EM_NORC 218 // Nanoradio Optimized RISC ++#define EM_CSR_KALIMBA 219 // CSR Kalimba architecture family ++#define EM_Z80 220 // Zilog Z80 ++#define EM_VISIUM 221 // Controls and Data Services VISIUMcore processor ++#define EM_FT32 222 // FTDI Chip FT32 high performance 32-bit RISC architecture ++#define EM_MOXIE 223 // Moxie processor family ++#define EM_AMDGPU 224 // AMD GPU architecture ++#define EM_RISCV 243 // RISC-V ++#define EM_LANAI 244 // Lanai processor ++#define EM_CEVA 245 // CEVA Processor Architecture Family ++#define EM_CEVA_X2 246 // CEVA X2 Processor Family ++#define EM_BPF 247 // Linux BPF – in-kernel virtual machine ++#define EM_GRAPHCORE_IPU 248 // Graphcore Intelligent Processing Unit ++#define EM_IMG1 249 // Imagination Technologies ++#define EM_NFP 250 // Netronome Flow Processor (P) ++#define EM_CSKY 252 // C-SKY processor family ++ ++// File version ++#define EV_NONE 0 ++#define EV_CURRENT 1 ++ ++// Identification index ++#define EI_MAG0 0 ++#define EI_MAG1 1 ++#define EI_MAG2 2 ++#define EI_MAG3 3 ++#define EI_CLASS 4 ++#define EI_DATA 5 ++#define EI_VERSION 6 ++#define EI_OSABI 7 ++#define EI_ABIVERSION 8 ++#define EI_PAD 9 ++#define EI_NIDENT 16 ++ ++// Magic number ++#define ELFMAG0 0x7F ++#define ELFMAG1 'E' ++#define ELFMAG2 'L' ++#define ELFMAG3 'F' ++ ++// File class ++#define ELFCLASSNONE 0 ++#define ELFCLASS32 1 ++#define ELFCLASS64 2 ++ ++// Encoding ++#define ELFDATANONE 0 ++#define ELFDATA2LSB 1 ++#define ELFDATA2MSB 2 ++ ++// OS extensions ++#define ELFOSABI_NONE 0 // No extensions or unspecified ++#define ELFOSABI_HPUX 1 // Hewlett-Packard HP-UX ++#define ELFOSABI_NETBSD 2 // NetBSD ++#define ELFOSABI_LINUX 3 // Linux ++#define ELFOSABI_SOLARIS 6 // Sun Solaris ++#define ELFOSABI_AIX 7 // AIX ++#define ELFOSABI_IRIX 8 // IRIX ++#define ELFOSABI_FREEBSD 9 // FreeBSD ++#define ELFOSABI_TRU64 10 // Compaq TRU64 UNIX ++#define ELFOSABI_MODESTO 11 // Novell Modesto ++#define ELFOSABI_OPENBSD 12 // Open BSD ++#define ELFOSABI_OPENVMS 13 // Open VMS ++#define ELFOSABI_NSK 14 // Hewlett-Packard Non-Stop Kernel ++#define ELFOSABI_AROS 15 // Amiga Research OS ++#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS ++// 64-255 Architecture-specific value range ++#define ELFOSABI_AMDGPU_HSA \ ++ 64 // AMDGPU OS for HSA compatible compute // kernels. ++#define ELFOSABI_AMDGPU_PAL \ ++ 65 // AMDGPU OS for AMD PAL compatible graphics // shaders and compute kernels. ++#define ELFOSABI_AMDGPU_MESA3D \ ++ 66 // AMDGPU OS for Mesa3D compatible graphics // shaders and compute kernels. ++ ++// AMDGPU specific e_flags ++#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask. ++#define EF_AMDGPU_XNACK \ ++ 0x100 // Indicates if the XNACK target feature is // enabled for all code contained in the ELF. ++// AMDGPU processors ++#define EF_AMDGPU_MACH_NONE 0x000 // Unspecified processor. ++#define EF_AMDGPU_MACH_R600_R600 0x001 ++#define EF_AMDGPU_MACH_R600_R630 0x002 ++#define EF_AMDGPU_MACH_R600_RS880 0x003 ++#define EF_AMDGPU_MACH_R600_RV670 0x004 ++#define EF_AMDGPU_MACH_R600_RV710 0x005 ++#define EF_AMDGPU_MACH_R600_RV730 0x006 ++#define EF_AMDGPU_MACH_R600_RV770 0x007 ++#define EF_AMDGPU_MACH_R600_CEDAR 0x008 ++#define EF_AMDGPU_MACH_R600_CYPRESS 0x009 ++#define EF_AMDGPU_MACH_R600_JUNIPER 0x00a ++#define EF_AMDGPU_MACH_R600_REDWOOD 0x00b ++#define EF_AMDGPU_MACH_R600_SUMO 0x00c ++#define EF_AMDGPU_MACH_R600_BARTS 0x00d ++#define EF_AMDGPU_MACH_R600_CAICOS 0x00e ++#define EF_AMDGPU_MACH_R600_CAYMAN 0x00f ++#define EF_AMDGPU_MACH_R600_TURKS 0x010 ++#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011 ++#define EF_AMDGPU_MACH_R600_RESERVED_LAST 0x01f ++#define EF_AMDGPU_MACH_R600_FIRST EF_AMDGPU_MACH_R600_R600 ++#define EF_AMDGPU_MACH_R600_LAST EF_AMDGPU_MACH_R600_TURKS ++#define EF_AMDGPU_MACH_AMDGCN_GFX600 0x020 ++#define EF_AMDGPU_MACH_AMDGCN_GFX601 0x021 ++#define EF_AMDGPU_MACH_AMDGCN_GFX700 0x022 ++#define EF_AMDGPU_MACH_AMDGCN_GFX701 0x023 ++#define EF_AMDGPU_MACH_AMDGCN_GFX702 0x024 ++#define EF_AMDGPU_MACH_AMDGCN_GFX703 0x025 ++#define EF_AMDGPU_MACH_AMDGCN_GFX704 0x026 ++#define EF_AMDGPU_MACH_AMDGCN_GFX801 0x028 ++#define EF_AMDGPU_MACH_AMDGCN_GFX802 0x029 ++#define EF_AMDGPU_MACH_AMDGCN_GFX803 0x02a ++#define EF_AMDGPU_MACH_AMDGCN_GFX810 0x02b ++#define EF_AMDGPU_MACH_AMDGCN_GFX900 0x02c ++#define EF_AMDGPU_MACH_AMDGCN_GFX902 0x02d ++#define EF_AMDGPU_MACH_AMDGCN_GFX904 0x02e ++#define EF_AMDGPU_MACH_AMDGCN_GFX906 0x02f ++#define EF_AMDGPU_MACH_AMDGCN_RESERVED0 0x027 ++#define EF_AMDGPU_MACH_AMDGCN_RESERVED1 0x030 ++#define EF_AMDGPU_MACH_AMDGCN_FIRST EF_AMDGPU_MACH_AMDGCN_GFX600 ++#define EF_AMDGPU_MACH_AMDGCN_LAST EF_AMDGPU_MACH_AMDGCN_GFX906 ++ ++///////////////////// ++// Sections constants ++ ++// Section indexes ++#define SHN_UNDEF 0 ++#define SHN_LORESERVE 0xFF00 ++#define SHN_LOPROC 0xFF00 ++#define SHN_HIPROC 0xFF1F ++#define SHN_LOOS 0xFF20 ++#define SHN_HIOS 0xFF3F ++#define SHN_ABS 0xFFF1 ++#define SHN_COMMON 0xFFF2 ++#define SHN_XINDEX 0xFFFF ++#define SHN_HIRESERVE 0xFFFF ++ ++// Section types ++#define SHT_NULL 0 ++#define SHT_PROGBITS 1 ++#define SHT_SYMTAB 2 ++#define SHT_STRTAB 3 ++#define SHT_RELA 4 ++#define SHT_HASH 5 ++#define SHT_DYNAMIC 6 ++#define SHT_NOTE 7 ++#define SHT_NOBITS 8 ++#define SHT_REL 9 ++#define SHT_SHLIB 10 ++#define SHT_DYNSYM 11 ++#define SHT_INIT_ARRAY 14 ++#define SHT_FINI_ARRAY 15 ++#define SHT_PREINIT_ARRAY 16 ++#define SHT_GROUP 17 ++#define SHT_SYMTAB_SHNDX 18 ++#define SHT_LOOS 0x60000000 ++#define SHT_HIOS 0x6fffffff ++#define SHT_LOPROC 0x70000000 ++#define SHT_HIPROC 0x7FFFFFFF ++#define SHT_LOUSER 0x80000000 ++#define SHT_HIUSER 0xFFFFFFFF ++ ++// Section attribute flags ++#define SHF_WRITE 0x1 ++#define SHF_ALLOC 0x2 ++#define SHF_EXECINSTR 0x4 ++#define SHF_MERGE 0x10 ++#define SHF_STRINGS 0x20 ++#define SHF_INFO_LINK 0x40 ++#define SHF_LINK_ORDER 0x80 ++#define SHF_OS_NONCONFORMING 0x100 ++#define SHF_GROUP 0x200 ++#define SHF_TLS 0x400 ++#define SHF_MASKOS 0x0ff00000 ++#define SHF_MASKPROC 0xF0000000 ++ ++// Section group flags ++#define GRP_COMDAT 0x1 ++#define GRP_MASKOS 0x0ff00000 ++#define GRP_MASKPROC 0xf0000000 ++ ++// Symbol binding ++#define STB_LOCAL 0 ++#define STB_GLOBAL 1 ++#define STB_WEAK 2 ++#define STB_LOOS 10 ++#define STB_HIOS 12 ++#define STB_MULTIDEF 13 ++#define STB_LOPROC 13 ++#define STB_HIPROC 15 ++ ++// Note types ++#define NT_AMDGPU_METADATA 1 ++#define NT_AMD_AMDGPU_HSA_METADATA 10 ++#define NT_AMD_AMDGPU_ISA 11 ++#define NT_AMD_AMDGPU_PAL_METADATA 12 ++ ++// Symbol types ++#define STT_NOTYPE 0 ++#define STT_OBJECT 1 ++#define STT_FUNC 2 ++#define STT_SECTION 3 ++#define STT_FILE 4 ++#define STT_COMMON 5 ++#define STT_TLS 6 ++#define STT_LOOS 10 ++#define STT_AMDGPU_HSA_KERNEL 10 ++#define STT_HIOS 12 ++#define STT_LOPROC 13 ++#define STT_HIPROC 15 ++ ++// Symbol visibility ++#define STV_DEFAULT 0 ++#define STV_INTERNAL 1 ++#define STV_HIDDEN 2 ++#define STV_PROTECTED 3 ++ ++// Undefined name ++#define STN_UNDEF 0 ++ ++// Relocation types ++#define R_386_NONE 0 ++#define R_X86_64_NONE 0 ++#define R_AMDGPU_NONE 0 ++#define R_386_32 1 ++#define R_X86_64_64 1 ++#define R_AMDGPU_ABS32_LO 1 ++#define R_386_PC32 2 ++#define R_X86_64_PC32 2 ++#define R_AMDGPU_ABS32_HI 2 ++#define R_386_GOT32 3 ++#define R_X86_64_GOT32 3 ++#define R_AMDGPU_ABS64 3 ++#define R_386_PLT32 4 ++#define R_X86_64_PLT32 4 ++#define R_AMDGPU_REL32 4 ++#define R_386_COPY 5 ++#define R_X86_64_COPY 5 ++#define R_AMDGPU_REL64 5 ++#define R_386_GLOB_DAT 6 ++#define R_X86_64_GLOB_DAT 6 ++#define R_AMDGPU_ABS32 6 ++#define R_386_JMP_SLOT 7 ++#define R_X86_64_JUMP_SLOT 7 ++#define R_AMDGPU_GOTPCREL 7 ++#define R_386_RELATIVE 8 ++#define R_X86_64_RELATIVE 8 ++#define R_AMDGPU_GOTPCREL32_LO 8 ++#define R_386_GOTOFF 9 ++#define R_X86_64_GOTPCREL 9 ++#define R_AMDGPU_GOTPCREL32_HI 9 ++#define R_386_GOTPC 10 ++#define R_X86_64_32 10 ++#define R_AMDGPU_REL32_LO 10 ++#define R_386_32PLT 11 ++#define R_X86_64_32S 11 ++#define R_AMDGPU_REL32_HI 11 ++#define R_X86_64_16 12 ++#define R_X86_64_PC16 13 ++#define R_AMDGPU_RELATIVE64 13 ++#define R_386_TLS_TPOFF 14 ++#define R_X86_64_8 14 ++#define R_386_TLS_IE 15 ++#define R_X86_64_PC8 15 ++#define R_386_TLS_GOTIE 16 ++#define R_X86_64_DTPMOD64 16 ++#define R_386_TLS_LE 17 ++#define R_X86_64_DTPOFF64 17 ++#define R_386_TLS_GD 18 ++#define R_X86_64_TPOFF64 18 ++#define R_386_TLS_LDM 19 ++#define R_X86_64_TLSGD 19 ++#define R_386_16 20 ++#define R_X86_64_TLSLD 20 ++#define R_386_PC16 21 ++#define R_X86_64_DTPOFF32 21 ++#define R_386_8 22 ++#define R_X86_64_GOTTPOFF 22 ++#define R_386_PC8 23 ++#define R_X86_64_TPOFF32 23 ++#define R_386_TLS_GD_32 24 ++#define R_X86_64_PC64 24 ++#define R_386_TLS_GD_PUSH 25 ++#define R_X86_64_GOTOFF64 25 ++#define R_386_TLS_GD_CALL 26 ++#define R_X86_64_GOTPC32 26 ++#define R_386_TLS_GD_POP 27 ++#define R_X86_64_GOT64 27 ++#define R_386_TLS_LDM_32 28 ++#define R_X86_64_GOTPCREL64 28 ++#define R_386_TLS_LDM_PUSH 29 ++#define R_X86_64_GOTPC64 29 ++#define R_386_TLS_LDM_CALL 30 ++#define R_X86_64_GOTPLT64 30 ++#define R_386_TLS_LDM_POP 31 ++#define R_X86_64_PLTOFF64 31 ++#define R_386_TLS_LDO_32 32 ++#define R_386_TLS_IE_32 33 ++#define R_386_TLS_LE_32 34 ++#define R_X86_64_GOTPC32_TLSDESC 34 ++#define R_386_TLS_DTPMOD32 35 ++#define R_X86_64_TLSDESC_CALL 35 ++#define R_386_TLS_DTPOFF32 36 ++#define R_X86_64_TLSDESC 36 ++#define R_386_TLS_TPOFF32 37 ++#define R_X86_64_IRELATIVE 37 ++#define R_386_SIZE32 38 ++#define R_386_TLS_GOTDESC 39 ++#define R_386_TLS_DESC_CALL 40 ++#define R_386_TLS_DESC 41 ++#define R_386_IRELATIVE 42 ++#define R_386_GOT32X 43 ++#define R_X86_64_GNU_VTINHERIT 250 ++#define R_X86_64_GNU_VTENTRY 251 ++ ++// Segment types ++#define PT_NULL 0 ++#define PT_LOAD 1 ++#define PT_DYNAMIC 2 ++#define PT_INTERP 3 ++#define PT_NOTE 4 ++#define PT_SHLIB 5 ++#define PT_PHDR 6 ++#define PT_TLS 7 ++#define PT_LOOS 0x60000000 ++#define PT_HIOS 0x6fffffff ++#define PT_LOPROC 0x70000000 ++#define PT_HIPROC 0x7FFFFFFF ++ ++// Segment flags ++#define PF_X 1 // Execute ++#define PF_W 2 // Write ++#define PF_R 4 // Read ++#define PF_MASKOS 0x0ff00000 // Unspecified ++#define PF_MASKPROC 0xf0000000 // Unspecified ++ ++// Dynamic Array Tags ++#define DT_NULL 0 ++#define DT_NEEDED 1 ++#define DT_PLTRELSZ 2 ++#define DT_PLTGOT 3 ++#define DT_HASH 4 ++#define DT_STRTAB 5 ++#define DT_SYMTAB 6 ++#define DT_RELA 7 ++#define DT_RELASZ 8 ++#define DT_RELAENT 9 ++#define DT_STRSZ 10 ++#define DT_SYMENT 11 ++#define DT_INIT 12 ++#define DT_FINI 13 ++#define DT_SONAME 14 ++#define DT_RPATH 15 ++#define DT_SYMBOLIC 16 ++#define DT_REL 17 ++#define DT_RELSZ 18 ++#define DT_RELENT 19 ++#define DT_PLTREL 20 ++#define DT_DEBUG 21 ++#define DT_TEXTREL 22 ++#define DT_JMPREL 23 ++#define DT_BIND_NOW 24 ++#define DT_INIT_ARRAY 25 ++#define DT_FINI_ARRAY 26 ++#define DT_INIT_ARRAYSZ 27 ++#define DT_FINI_ARRAYSZ 28 ++#define DT_RUNPATH 29 ++#define DT_FLAGS 30 ++#define DT_ENCODING 32 ++#define DT_PREINIT_ARRAY 32 ++#define DT_PREINIT_ARRAYSZ 33 ++#define DT_MAXPOSTAGS 34 ++#define DT_LOOS 0x6000000D ++#define DT_HIOS 0x6ffff000 ++#define DT_LOPROC 0x70000000 ++#define DT_HIPROC 0x7FFFFFFF ++ ++// DT_FLAGS values ++#define DF_ORIGIN 0x1 ++#define DF_SYMBOLIC 0x2 ++#define DF_TEXTREL 0x4 ++#define DF_BIND_NOW 0x8 ++#define DF_STATIC_TLS 0x10 ++ ++// ELF file header ++struct Elf32_Ehdr ++{ ++ unsigned char e_ident[EI_NIDENT]; ++ Elf_Half e_type; ++ Elf_Half e_machine; ++ Elf_Word e_version; ++ Elf32_Addr e_entry; ++ Elf32_Off e_phoff; ++ Elf32_Off e_shoff; ++ Elf_Word e_flags; ++ Elf_Half e_ehsize; ++ Elf_Half e_phentsize; ++ Elf_Half e_phnum; ++ Elf_Half e_shentsize; ++ Elf_Half e_shnum; ++ Elf_Half e_shstrndx; ++}; ++ ++struct Elf64_Ehdr ++{ ++ unsigned char e_ident[EI_NIDENT]; ++ Elf_Half e_type; ++ Elf_Half e_machine; ++ Elf_Word e_version; ++ Elf64_Addr e_entry; ++ Elf64_Off e_phoff; ++ Elf64_Off e_shoff; ++ Elf_Word e_flags; ++ Elf_Half e_ehsize; ++ Elf_Half e_phentsize; ++ Elf_Half e_phnum; ++ Elf_Half e_shentsize; ++ Elf_Half e_shnum; ++ Elf_Half e_shstrndx; ++}; ++ ++// Section header ++struct Elf32_Shdr ++{ ++ Elf_Word sh_name; ++ Elf_Word sh_type; ++ Elf_Word sh_flags; ++ Elf32_Addr sh_addr; ++ Elf32_Off sh_offset; ++ Elf_Word sh_size; ++ Elf_Word sh_link; ++ Elf_Word sh_info; ++ Elf_Word sh_addralign; ++ Elf_Word sh_entsize; ++}; ++ ++struct Elf64_Shdr ++{ ++ Elf_Word sh_name; ++ Elf_Word sh_type; ++ Elf_Xword sh_flags; ++ Elf64_Addr sh_addr; ++ Elf64_Off sh_offset; ++ Elf_Xword sh_size; ++ Elf_Word sh_link; ++ Elf_Word sh_info; ++ Elf_Xword sh_addralign; ++ Elf_Xword sh_entsize; ++}; ++ ++// Segment header ++struct Elf32_Phdr ++{ ++ Elf_Word p_type; ++ Elf32_Off p_offset; ++ Elf32_Addr p_vaddr; ++ Elf32_Addr p_paddr; ++ Elf_Word p_filesz; ++ Elf_Word p_memsz; ++ Elf_Word p_flags; ++ Elf_Word p_align; ++}; ++ ++struct Elf64_Phdr ++{ ++ Elf_Word p_type; ++ Elf_Word p_flags; ++ Elf64_Off p_offset; ++ Elf64_Addr p_vaddr; ++ Elf64_Addr p_paddr; ++ Elf_Xword p_filesz; ++ Elf_Xword p_memsz; ++ Elf_Xword p_align; ++}; ++ ++// Symbol table entry ++struct Elf32_Sym ++{ ++ Elf_Word st_name; ++ Elf32_Addr st_value; ++ Elf_Word st_size; ++ unsigned char st_info; ++ unsigned char st_other; ++ Elf_Half st_shndx; ++}; ++ ++struct Elf64_Sym ++{ ++ Elf_Word st_name; ++ unsigned char st_info; ++ unsigned char st_other; ++ Elf_Half st_shndx; ++ Elf64_Addr st_value; ++ Elf_Xword st_size; ++}; ++ ++#define ELF_ST_BIND( i ) ( ( i ) >> 4 ) ++#define ELF_ST_TYPE( i ) ( (i)&0xf ) ++#define ELF_ST_INFO( b, t ) ( ( ( b ) << 4 ) + ( (t)&0xf ) ) ++ ++#define ELF_ST_VISIBILITY( o ) ( (o)&0x3 ) ++ ++// Relocation entries ++struct Elf32_Rel ++{ ++ Elf32_Addr r_offset; ++ Elf_Word r_info; ++}; ++ ++struct Elf32_Rela ++{ ++ Elf32_Addr r_offset; ++ Elf_Word r_info; ++ Elf_Sword r_addend; ++}; ++ ++struct Elf64_Rel ++{ ++ Elf64_Addr r_offset; ++ Elf_Xword r_info; ++}; ++ ++struct Elf64_Rela ++{ ++ Elf64_Addr r_offset; ++ Elf_Xword r_info; ++ Elf_Sxword r_addend; ++}; ++ ++#define ELF32_R_SYM( i ) ( ( i ) >> 8 ) ++#define ELF32_R_TYPE( i ) ( (unsigned char)( i ) ) ++#define ELF32_R_INFO( s, t ) ( ( ( s ) << 8 ) + (unsigned char)( t ) ) ++ ++#define ELF64_R_SYM( i ) ( ( i ) >> 32 ) ++#define ELF64_R_TYPE( i ) ( (i)&0xffffffffL ) ++#define ELF64_R_INFO( s, t ) \ ++ ( ( ( ( int64_t )( s ) ) << 32 ) + ( (t)&0xffffffffL ) ) ++ ++// Dynamic structure ++struct Elf32_Dyn ++{ ++ Elf_Sword d_tag; ++ union { ++ Elf_Word d_val; ++ Elf32_Addr d_ptr; ++ } d_un; ++}; ++ ++struct Elf64_Dyn ++{ ++ Elf_Sxword d_tag; ++ union { ++ Elf_Xword d_val; ++ Elf64_Addr d_ptr; ++ } d_un; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFTYPES_H ++ ++/*** End of inlined file: elf_types.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_version.hpp ***/ ++#define ELFIO_VERSION "3.8" ++ ++/*** End of inlined file: elfio_version.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_utils.hpp ***/ ++#ifndef ELFIO_UTILS_HPP ++#define ELFIO_UTILS_HPP ++ ++#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \ ++ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } ++#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \ ++ void set_##NAME( TYPE value ) \ ++ { \ ++ FIELD = value; \ ++ FIELD = ( *convertor )( FIELD ); \ ++ } ++#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \ ++ TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \ ++ void set_##NAME( TYPE value ) \ ++ { \ ++ FIELD = value; \ ++ FIELD = ( *convertor )( FIELD ); \ ++ } ++ ++#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0 ++ ++#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \ ++ virtual void set_##NAME( TYPE value ) = 0 ++ ++#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \ ++ virtual TYPE get_##NAME() const = 0; \ ++ virtual void set_##NAME( TYPE value ) = 0 ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++class endianess_convertor ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ endianess_convertor() { need_conversion = false; } ++ ++ //------------------------------------------------------------------------------ ++ void setup( unsigned char elf_file_encoding ) ++ { ++ need_conversion = ( elf_file_encoding != get_host_encoding() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint64_t operator()( uint64_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ( ( value & 0x00000000000000FFull ) << 56 ) | ++ ( ( value & 0x000000000000FF00ull ) << 40 ) | ++ ( ( value & 0x0000000000FF0000ull ) << 24 ) | ++ ( ( value & 0x00000000FF000000ull ) << 8 ) | ++ ( ( value & 0x000000FF00000000ull ) >> 8 ) | ++ ( ( value & 0x0000FF0000000000ull ) >> 24 ) | ++ ( ( value & 0x00FF000000000000ull ) >> 40 ) | ++ ( ( value & 0xFF00000000000000ull ) >> 56 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int64_t operator()( int64_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int64_t )( *this )( (uint64_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint32_t operator()( uint32_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ++ ( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) | ++ ( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int32_t operator()( int32_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int32_t )( *this )( (uint32_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ uint16_t operator()( uint16_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 ); ++ ++ return value; ++ } ++ ++ //------------------------------------------------------------------------------ ++ int16_t operator()( int16_t value ) const ++ { ++ if ( !need_conversion ) { ++ return value; ++ } ++ return ( int16_t )( *this )( (uint16_t)value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ int8_t operator()( int8_t value ) const { return value; } ++ ++ //------------------------------------------------------------------------------ ++ uint8_t operator()( uint8_t value ) const { return value; } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ unsigned char get_host_encoding() const ++ { ++ static const int tmp = 1; ++ if ( 1 == *(const char*)&tmp ) { ++ return ELFDATA2LSB; ++ } ++ else { ++ return ELFDATA2MSB; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ bool need_conversion; ++}; ++ ++//------------------------------------------------------------------------------ ++inline uint32_t elf_hash( const unsigned char* name ) ++{ ++ uint32_t h = 0, g; ++ while ( *name ) { ++ h = ( h << 4 ) + *name++; ++ g = h & 0xf0000000; ++ if ( g != 0 ) ++ h ^= g >> 24; ++ h &= ~g; ++ } ++ return h; ++} ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_UTILS_HPP ++ ++/*** End of inlined file: elfio_utils.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_header.hpp ***/ ++#ifndef ELF_HEADER_HPP ++#define ELF_HEADER_HPP ++ ++#include <iostream> ++ ++namespace ELFIO { ++ ++class elf_header ++{ ++ public: ++ virtual ~elf_header(){}; ++ virtual bool load( std::istream& stream ) = 0; ++ virtual bool save( std::ostream& stream ) const = 0; ++ ++ // ELF header functions ++ ELFIO_GET_ACCESS_DECL( unsigned char, class ); ++ ELFIO_GET_ACCESS_DECL( unsigned char, elf_version ); ++ ELFIO_GET_ACCESS_DECL( unsigned char, encoding ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, header_size ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size ); ++ ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size ); ++ ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version ); ++ ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi ); ++ ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index ); ++}; ++ ++template <class T> struct elf_header_impl_types; ++template <> struct elf_header_impl_types<Elf32_Ehdr> ++{ ++ typedef Elf32_Phdr Phdr_type; ++ typedef Elf32_Shdr Shdr_type; ++ static const unsigned char file_class = ELFCLASS32; ++}; ++template <> struct elf_header_impl_types<Elf64_Ehdr> ++{ ++ typedef Elf64_Phdr Phdr_type; ++ typedef Elf64_Shdr Shdr_type; ++ static const unsigned char file_class = ELFCLASS64; ++}; ++ ++template <class T> class elf_header_impl : public elf_header ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ elf_header_impl( endianess_convertor* convertor_, unsigned char encoding ) ++ { ++ convertor = convertor_; ++ ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ ++ header.e_ident[EI_MAG0] = ELFMAG0; ++ header.e_ident[EI_MAG1] = ELFMAG1; ++ header.e_ident[EI_MAG2] = ELFMAG2; ++ header.e_ident[EI_MAG3] = ELFMAG3; ++ header.e_ident[EI_CLASS] = elf_header_impl_types<T>::file_class; ++ header.e_ident[EI_DATA] = encoding; ++ header.e_ident[EI_VERSION] = EV_CURRENT; ++ header.e_version = ( *convertor )( (Elf_Word)EV_CURRENT ); ++ header.e_ehsize = ( sizeof( header ) ); ++ header.e_ehsize = ( *convertor )( header.e_ehsize ); ++ header.e_shstrndx = ( *convertor )( (Elf_Half)1 ); ++ header.e_phentsize = ++ sizeof( typename elf_header_impl_types<T>::Phdr_type ); ++ header.e_shentsize = ++ sizeof( typename elf_header_impl_types<T>::Shdr_type ); ++ header.e_phentsize = ( *convertor )( header.e_phentsize ); ++ header.e_shentsize = ( *convertor )( header.e_shentsize ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( std::istream& stream ) ++ { ++ stream.seekg( 0 ); ++ stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); ++ ++ return ( stream.gcount() == sizeof( header ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( std::ostream& stream ) const ++ { ++ stream.seekp( 0 ); ++ stream.write( reinterpret_cast<const char*>( &header ), ++ sizeof( header ) ); ++ ++ return stream.good(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ // ELF header functions ++ ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] ); ++ ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] ); ++ ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] ); ++ ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize ); ++ ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize ); ++ ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize ); ++ ++ ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version ); ++ ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] ); ++ ELFIO_GET_SET_ACCESS( unsigned char, ++ abi_version, ++ header.e_ident[EI_ABIVERSION] ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum ); ++ ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff ); ++ ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum ); ++ ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff ); ++ ++ private: ++ T header; ++ endianess_convertor* convertor; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELF_HEADER_HPP ++ ++/*** End of inlined file: elfio_header.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_section.hpp ***/ ++#ifndef ELFIO_SECTION_HPP ++#define ELFIO_SECTION_HPP ++ ++#include <string> ++#include <iostream> ++#include <new> ++ ++namespace ELFIO { ++ ++class section ++{ ++ friend class elfio; ++ ++ public: ++ virtual ~section(){}; ++ ++ ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ++ ELFIO_GET_SET_ACCESS_DECL( std::string, name ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset ); ++ ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); ++ ++ virtual const char* get_data() const = 0; ++ virtual void set_data( const char* pData, Elf_Word size ) = 0; ++ virtual void set_data( const std::string& data ) = 0; ++ virtual void append_data( const char* pData, Elf_Word size ) = 0; ++ virtual void append_data( const std::string& data ) = 0; ++ virtual size_t get_stream_size() const = 0; ++ virtual void set_stream_size( size_t value ) = 0; ++ ++ protected: ++ ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ++ ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ++ ++ virtual void load( std::istream& stream, std::streampos header_offset ) = 0; ++ virtual void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) = 0; ++ virtual bool is_address_initialized() const = 0; ++}; ++ ++template <class T> class section_impl : public section ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ section_impl( const endianess_convertor* convertor_ ) ++ : convertor( convertor_ ) ++ { ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ is_address_set = false; ++ data = 0; ++ data_size = 0; ++ index = 0; ++ stream_size = 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ ~section_impl() { delete[] data; } ++ ++ //------------------------------------------------------------------------------ ++ // Section info functions ++ ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); ++ ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr ); ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_index() const { return index; } ++ ++ //------------------------------------------------------------------------------ ++ std::string get_name() const { return name; } ++ ++ //------------------------------------------------------------------------------ ++ void set_name( std::string name_ ) { name = name_; } ++ ++ //------------------------------------------------------------------------------ ++ void set_address( Elf64_Addr value ) ++ { ++ header.sh_addr = value; ++ header.sh_addr = ( *convertor )( header.sh_addr ); ++ is_address_set = true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_address_initialized() const { return is_address_set; } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_data() const { return data; } ++ ++ //------------------------------------------------------------------------------ ++ void set_data( const char* raw_data, Elf_Word size ) ++ { ++ if ( get_type() != SHT_NOBITS ) { ++ delete[] data; ++ data = new ( std::nothrow ) char[size]; ++ if ( 0 != data && 0 != raw_data ) { ++ data_size = size; ++ std::copy( raw_data, raw_data + size, data ); ++ } ++ else { ++ data_size = 0; ++ } ++ } ++ ++ set_size( data_size ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void set_data( const std::string& str_data ) ++ { ++ return set_data( str_data.c_str(), (Elf_Word)str_data.size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void append_data( const char* raw_data, Elf_Word size ) ++ { ++ if ( get_type() != SHT_NOBITS ) { ++ if ( get_size() + size < data_size ) { ++ std::copy( raw_data, raw_data + size, data + get_size() ); ++ } ++ else { ++ data_size = 2 * ( data_size + size ); ++ char* new_data = new ( std::nothrow ) char[data_size]; ++ ++ if ( 0 != new_data ) { ++ std::copy( data, data + get_size(), new_data ); ++ std::copy( raw_data, raw_data + size, ++ new_data + get_size() ); ++ delete[] data; ++ data = new_data; ++ } ++ else { ++ size = 0; ++ } ++ } ++ set_size( get_size() + size ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void append_data( const std::string& str_data ) ++ { ++ return append_data( str_data.c_str(), (Elf_Word)str_data.size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ protected: ++ //------------------------------------------------------------------------------ ++ ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset ); ++ ++ //------------------------------------------------------------------------------ ++ void set_index( Elf_Half value ) { index = value; } ++ ++ //------------------------------------------------------------------------------ ++ void load( std::istream& stream, std::streampos header_offset ) ++ { ++ std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), ++ '\0' ); ++ ++ stream.seekg( 0, stream.end ); ++ set_stream_size( stream.tellg() ); ++ ++ stream.seekg( header_offset ); ++ stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) ); ++ ++ Elf_Xword size = get_size(); ++ if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() && ++ size < get_stream_size() ) { ++ data = new ( std::nothrow ) char[size + 1]; ++ ++ if ( ( 0 != size ) && ( 0 != data ) ) { ++ stream.seekg( ( *convertor )( header.sh_offset ) ); ++ stream.read( data, size ); ++ data[size] = 0; // Ensure data is ended with 0 to avoid oob read ++ data_size = size; ++ } ++ else { ++ data_size = 0; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) ++ { ++ if ( 0 != get_index() ) { ++ header.sh_offset = data_offset; ++ header.sh_offset = ( *convertor )( header.sh_offset ); ++ } ++ ++ save_header( stream, header_offset ); ++ if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && ++ get_size() != 0 && data != 0 ) { ++ save_data( stream, data_offset ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void save_header( std::ostream& stream, std::streampos header_offset ) const ++ { ++ stream.seekp( header_offset ); ++ stream.write( reinterpret_cast<const char*>( &header ), ++ sizeof( header ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save_data( std::ostream& stream, std::streampos data_offset ) const ++ { ++ stream.seekp( data_offset ); ++ stream.write( get_data(), get_size() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ size_t get_stream_size() const { return stream_size; } ++ ++ //------------------------------------------------------------------------------ ++ void set_stream_size( size_t value ) { stream_size = value; } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ T header; ++ Elf_Half index; ++ std::string name; ++ char* data; ++ Elf_Word data_size; ++ const endianess_convertor* convertor; ++ bool is_address_set; ++ size_t stream_size; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SECTION_HPP ++ ++/*** End of inlined file: elfio_section.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_segment.hpp ***/ ++#ifndef ELFIO_SEGMENT_HPP ++#define ELFIO_SEGMENT_HPP ++ ++#include <iostream> ++#include <vector> ++#include <new> ++ ++namespace ELFIO { ++ ++class segment ++{ ++ friend class elfio; ++ ++ public: ++ virtual ~segment(){}; ++ ++ ELFIO_GET_ACCESS_DECL( Elf_Half, index ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size ); ++ ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size ); ++ ELFIO_GET_ACCESS_DECL( Elf64_Off, offset ); ++ ++ virtual const char* get_data() const = 0; ++ ++ virtual Elf_Half add_section_index( Elf_Half index, ++ Elf_Xword addr_align ) = 0; ++ virtual Elf_Half get_sections_num() const = 0; ++ virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0; ++ virtual bool is_offset_initialized() const = 0; ++ ++ protected: ++ ELFIO_SET_ACCESS_DECL( Elf64_Off, offset ); ++ ELFIO_SET_ACCESS_DECL( Elf_Half, index ); ++ ++ virtual const std::vector<Elf_Half>& get_sections() const = 0; ++ virtual void load( std::istream& stream, std::streampos header_offset ) = 0; ++ virtual void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) = 0; ++}; ++ ++//------------------------------------------------------------------------------ ++template <class T> class segment_impl : public segment ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ segment_impl( endianess_convertor* convertor_ ) ++ : stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ ) ++ { ++ is_offset_set = false; ++ std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ virtual ~segment_impl() { delete[] data; } ++ ++ //------------------------------------------------------------------------------ ++ // Section info functions ++ ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); ++ ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); ++ ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); ++ ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); ++ ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset ); ++ size_t stream_size; ++ ++ //------------------------------------------------------------------------------ ++ size_t get_stream_size() const { return stream_size; } ++ ++ //------------------------------------------------------------------------------ ++ void set_stream_size( size_t value ) { stream_size = value; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_index() const { return index; } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_data() const { return data; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align ) ++ { ++ sections.push_back( sec_index ); ++ if ( addr_align > get_align() ) { ++ set_align( addr_align ); ++ } ++ ++ return (Elf_Half)sections.size(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_section_index_at( Elf_Half num ) const ++ { ++ if ( num < sections.size() ) { ++ return sections[num]; ++ } ++ ++ return Elf_Half( -1 ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ protected: ++ //------------------------------------------------------------------------------ ++ ++ //------------------------------------------------------------------------------ ++ void set_offset( Elf64_Off value ) ++ { ++ ph.p_offset = value; ++ ph.p_offset = ( *convertor )( ph.p_offset ); ++ is_offset_set = true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_offset_initialized() const { return is_offset_set; } ++ ++ //------------------------------------------------------------------------------ ++ const std::vector<Elf_Half>& get_sections() const { return sections; } ++ ++ //------------------------------------------------------------------------------ ++ void set_index( Elf_Half value ) { index = value; } ++ ++ //------------------------------------------------------------------------------ ++ void load( std::istream& stream, std::streampos header_offset ) ++ { ++ ++ stream.seekg( 0, stream.end ); ++ set_stream_size( stream.tellg() ); ++ ++ stream.seekg( header_offset ); ++ stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) ); ++ is_offset_set = true; ++ ++ if ( PT_NULL != get_type() && 0 != get_file_size() ) { ++ stream.seekg( ( *convertor )( ph.p_offset ) ); ++ Elf_Xword size = get_file_size(); ++ ++ if ( size > get_stream_size() ) { ++ data = 0; ++ } ++ else { ++ data = new (std::nothrow) char[size + 1]; ++ ++ if ( 0 != data ) { ++ stream.read( data, size ); ++ data[size] = 0; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void save( std::ostream& stream, ++ std::streampos header_offset, ++ std::streampos data_offset ) ++ { ++ ph.p_offset = data_offset; ++ ph.p_offset = ( *convertor )( ph.p_offset ); ++ stream.seekp( header_offset ); ++ stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ T ph; ++ Elf_Half index; ++ char* data; ++ std::vector<Elf_Half> sections; ++ endianess_convertor* convertor; ++ bool is_offset_set; ++}; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SEGMENT_HPP ++ ++/*** End of inlined file: elfio_segment.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_strings.hpp ***/ ++#ifndef ELFIO_STRINGS_HPP ++#define ELFIO_STRINGS_HPP ++ ++#include <cstdlib> ++#include <cstring> ++#include <string> ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class string_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ string_section_accessor_template( S* section_ ) : string_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ const char* get_string( Elf_Word index ) const ++ { ++ if ( string_section ) { ++ if ( index < string_section->get_size() ) { ++ const char* data = string_section->get_data(); ++ if ( 0 != data ) { ++ return data + index; ++ } ++ } ++ } ++ ++ return 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_string( const char* str ) ++ { ++ Elf_Word current_position = 0; ++ ++ if ( string_section ) { ++ // Strings are addeded to the end of the current section data ++ current_position = (Elf_Word)string_section->get_size(); ++ ++ if ( current_position == 0 ) { ++ char empty_string = '\0'; ++ string_section->append_data( &empty_string, 1 ); ++ current_position++; ++ } ++ string_section->append_data( str, ++ (Elf_Word)std::strlen( str ) + 1 ); ++ } ++ ++ return current_position; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_string( const std::string& str ) ++ { ++ return add_string( str.c_str() ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ S* string_section; ++}; ++ ++using string_section_accessor = string_section_accessor_template<section>; ++using const_string_section_accessor = ++ string_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_STRINGS_HPP ++ ++/*** End of inlined file: elfio_strings.hpp ***/ ++ ++#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \ ++ TYPE get_##FNAME() const { return header ? ( header->get_##FNAME() ) : 0; } ++ ++#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \ ++ TYPE get_##FNAME() const \ ++ { \ ++ return header ? ( header->get_##FNAME() ) : 0; \ ++ } \ ++ void set_##FNAME( TYPE val ) \ ++ { \ ++ if ( header ) { \ ++ header->set_##FNAME( val ); \ ++ } \ ++ } ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++class elfio ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ elfio() : sections( this ), segments( this ) ++ { ++ header = 0; ++ current_file_pos = 0; ++ create( ELFCLASS32, ELFDATA2LSB ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ ~elfio() { clean(); } ++ ++ //------------------------------------------------------------------------------ ++ void create( unsigned char file_class, unsigned char encoding ) ++ { ++ clean(); ++ convertor.setup( encoding ); ++ header = create_header( file_class, encoding ); ++ create_mandatory_sections(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( const std::string& file_name ) ++ { ++ std::ifstream stream; ++ stream.open( file_name.c_str(), std::ios::in | std::ios::binary ); ++ if ( !stream ) { ++ return false; ++ } ++ ++ return load( stream ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load( std::istream& stream ) ++ { ++ clean(); ++ ++ unsigned char e_ident[EI_NIDENT]; ++ // Read ELF file signature ++ stream.read( reinterpret_cast<char*>( &e_ident ), sizeof( e_ident ) ); ++ ++ // Is it ELF file? ++ if ( stream.gcount() != sizeof( e_ident ) || ++ e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || ++ e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 ) { ++ return false; ++ } ++ ++ if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) && ++ ( e_ident[EI_CLASS] != ELFCLASS32 ) ) { ++ return false; ++ } ++ ++ convertor.setup( e_ident[EI_DATA] ); ++ header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] ); ++ if ( 0 == header ) { ++ return false; ++ } ++ if ( !header->load( stream ) ) { ++ return false; ++ } ++ ++ load_sections( stream ); ++ bool is_still_good = load_segments( stream ); ++ return is_still_good; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( const std::string& file_name ) ++ { ++ std::ofstream stream; ++ stream.open( file_name.c_str(), std::ios::out | std::ios::binary ); ++ if ( !stream ) { ++ return false; ++ } ++ ++ return save( stream ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save( std::ostream& stream ) ++ { ++ if ( !stream || !header ) { ++ return false; ++ } ++ ++ bool is_still_good = true; ++ // Define layout specific header fields ++ // The position of the segment table is fixed after the header. ++ // The position of the section table is variable and needs to be fixed ++ // before saving. ++ header->set_segments_num( segments.size() ); ++ header->set_segments_offset( segments.size() ? header->get_header_size() ++ : 0 ); ++ header->set_sections_num( sections.size() ); ++ header->set_sections_offset( 0 ); ++ ++ // Layout the first section right after the segment table ++ current_file_pos = header->get_header_size() + ++ header->get_segment_entry_size() * ++ (Elf_Xword)header->get_segments_num(); ++ ++ calc_segment_alignment(); ++ ++ is_still_good = layout_segments_and_their_sections(); ++ is_still_good = is_still_good && layout_sections_without_segments(); ++ is_still_good = is_still_good && layout_section_table(); ++ ++ is_still_good = is_still_good && save_header( stream ); ++ is_still_good = is_still_good && save_sections( stream ); ++ is_still_good = is_still_good && save_segments( stream ); ++ ++ return is_still_good; ++ } ++ ++ //------------------------------------------------------------------------------ ++ // ELF header access functions ++ ELFIO_HEADER_ACCESS_GET( unsigned char, class ); ++ ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version ); ++ ELFIO_HEADER_ACCESS_GET( unsigned char, encoding ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Word, version ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size ); ++ ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size ); ++ ++ ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi ); ++ ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset ); ++ ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index ); ++ ++ //------------------------------------------------------------------------------ ++ const endianess_convertor& get_convertor() const { return convertor; } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_default_entry_size( Elf_Word section_type ) const ++ { ++ switch ( section_type ) { ++ case SHT_RELA: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Rela ); ++ } ++ else { ++ return sizeof( Elf32_Rela ); ++ } ++ case SHT_REL: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Rel ); ++ } ++ else { ++ return sizeof( Elf32_Rel ); ++ } ++ case SHT_SYMTAB: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Sym ); ++ } ++ else { ++ return sizeof( Elf32_Sym ); ++ } ++ case SHT_DYNAMIC: ++ if ( header->get_class() == ELFCLASS64 ) { ++ return sizeof( Elf64_Dyn ); ++ } ++ else { ++ return sizeof( Elf32_Dyn ); ++ } ++ default: ++ return 0; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ bool is_offset_in_section( Elf64_Off offset, const section* sec ) const ++ { ++ return ( offset >= sec->get_offset() ) && ++ ( offset < ( sec->get_offset() + sec->get_size() ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ public: ++ //! returns an empty string if no problems are detected, ++ //! or a string containing an error message if problems are found ++ std::string validate() const ++ { ++ ++ // check for overlapping sections in the file ++ for ( int i = 0; i < sections.size(); ++i ) { ++ for ( int j = i + 1; j < sections.size(); ++j ) { ++ const section* a = sections[i]; ++ const section* b = sections[j]; ++ if ( !( a->get_type() & SHT_NOBITS ) && ++ !( b->get_type() & SHT_NOBITS ) && ( a->get_size() > 0 ) && ++ ( b->get_size() > 0 ) && ( a->get_offset() > 0 ) && ++ ( b->get_offset() > 0 ) ) { ++ if ( is_offset_in_section( a->get_offset(), b ) || ++ is_offset_in_section( ++ a->get_offset() + a->get_size() - 1, b ) || ++ is_offset_in_section( b->get_offset(), a ) || ++ is_offset_in_section( ++ b->get_offset() + b->get_size() - 1, a ) ) { ++ return "Sections " + a->get_name() + " and " + ++ b->get_name() + " overlap in file"; ++ } ++ } ++ } ++ } ++ ++ // more checks to be added here... ++ ++ return ""; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void clean() ++ { ++ delete header; ++ header = 0; ++ ++ std::vector<section*>::const_iterator it; ++ for ( it = sections_.begin(); it != sections_.end(); ++it ) { ++ delete *it; ++ } ++ sections_.clear(); ++ ++ std::vector<segment*>::const_iterator it1; ++ for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) { ++ delete *it1; ++ } ++ segments_.clear(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ elf_header* create_header( unsigned char file_class, ++ unsigned char encoding ) ++ { ++ elf_header* new_header = 0; ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_header = ++ new elf_header_impl<Elf64_Ehdr>( &convertor, encoding ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_header = ++ new elf_header_impl<Elf32_Ehdr>( &convertor, encoding ); ++ } ++ else { ++ return 0; ++ } ++ ++ return new_header; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* create_section() ++ { ++ section* new_section; ++ unsigned char file_class = get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_section = new section_impl<Elf64_Shdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_section = new section_impl<Elf32_Shdr>( &convertor ); ++ } ++ else { ++ return 0; ++ } ++ ++ new_section->set_index( (Elf_Half)sections_.size() ); ++ sections_.push_back( new_section ); ++ ++ return new_section; ++ } ++ ++ //------------------------------------------------------------------------------ ++ segment* create_segment() ++ { ++ segment* new_segment; ++ unsigned char file_class = header->get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ new_segment = new segment_impl<Elf64_Phdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ new_segment = new segment_impl<Elf32_Phdr>( &convertor ); ++ } ++ else { ++ return 0; ++ } ++ ++ new_segment->set_index( (Elf_Half)segments_.size() ); ++ segments_.push_back( new_segment ); ++ ++ return new_segment; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void create_mandatory_sections() ++ { ++ // Create null section without calling to 'add_section' as no string ++ // section containing section names exists yet ++ section* sec0 = create_section(); ++ sec0->set_index( 0 ); ++ sec0->set_name( "" ); ++ sec0->set_name_string_offset( 0 ); ++ ++ set_section_name_str_index( 1 ); ++ section* shstrtab = sections.add( ".shstrtab" ); ++ shstrtab->set_type( SHT_STRTAB ); ++ shstrtab->set_addr_align( 1 ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half load_sections( std::istream& stream ) ++ { ++ Elf_Half entry_size = header->get_section_entry_size(); ++ Elf_Half num = header->get_sections_num(); ++ Elf64_Off offset = header->get_sections_offset(); ++ ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ section* sec = create_section(); ++ sec->load( stream, (std::streamoff)offset + ++ (std::streampos)i * entry_size ); ++ sec->set_index( i ); ++ // To mark that the section is not permitted to reassign address ++ // during layout calculation ++ sec->set_address( sec->get_address() ); ++ } ++ ++ Elf_Half shstrndx = get_section_name_str_index(); ++ ++ if ( SHN_UNDEF != shstrndx ) { ++ string_section_accessor str_reader( sections[shstrndx] ); ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ Elf_Word section_offset = sections[i]->get_name_string_offset(); ++ const char* p = str_reader.get_string( section_offset ); ++ if ( p != 0 ) { ++ sections[i]->set_name( p ); ++ } ++ } ++ } ++ ++ return num; ++ } ++ ++ //------------------------------------------------------------------------------ ++ //! Checks whether the addresses of the section entirely fall within the given segment. ++ //! It doesn't matter if the addresses are memory addresses, or file offsets, ++ //! they just need to be in the same address space ++ bool is_sect_in_seg( Elf64_Off sect_begin, ++ Elf_Xword sect_size, ++ Elf64_Off seg_begin, ++ Elf64_Off seg_end ) ++ { ++ return ( seg_begin <= sect_begin ) && ++ ( sect_begin + sect_size <= seg_end ) && ++ ( sect_begin < ++ seg_end ); // this is important criteria when sect_size == 0 ++ // Example: seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11) ++ // sect_begin=12, sect_size=0 -> shall return false! ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool load_segments( std::istream& stream ) ++ { ++ Elf_Half entry_size = header->get_segment_entry_size(); ++ Elf_Half num = header->get_segments_num(); ++ Elf64_Off offset = header->get_segments_offset(); ++ ++ for ( Elf_Half i = 0; i < num; ++i ) { ++ segment* seg; ++ unsigned char file_class = header->get_class(); ++ ++ if ( file_class == ELFCLASS64 ) { ++ seg = new segment_impl<Elf64_Phdr>( &convertor ); ++ } ++ else if ( file_class == ELFCLASS32 ) { ++ seg = new segment_impl<Elf32_Phdr>( &convertor ); ++ } ++ else { ++ return false; ++ } ++ ++ seg->load( stream, (std::streamoff)offset + ++ (std::streampos)i * entry_size ); ++ seg->set_index( i ); ++ ++ // Add sections to the segments (similar to readelfs algorithm) ++ Elf64_Off segBaseOffset = seg->get_offset(); ++ Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size(); ++ Elf64_Off segVBaseAddr = seg->get_virtual_address(); ++ Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size(); ++ for ( Elf_Half j = 0; j < sections.size(); ++j ) { ++ const section* psec = sections[j]; ++ ++ // SHF_ALLOC sections are matched based on the virtual address ++ // otherwise the file offset is matched ++ if ( ( psec->get_flags() & SHF_ALLOC ) ++ ? is_sect_in_seg( psec->get_address(), ++ psec->get_size(), segVBaseAddr, ++ segVEndAddr ) ++ : is_sect_in_seg( psec->get_offset(), psec->get_size(), ++ segBaseOffset, segEndOffset ) ) { ++ // Alignment of segment shall not be updated, to preserve original value ++ // It will be re-calculated on saving. ++ seg->add_section_index( psec->get_index(), 0 ); ++ } ++ } ++ ++ // Add section into the segments' container ++ segments_.push_back( seg ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save_header( std::ostream& stream ) { return header->save( stream ); } ++ ++ //------------------------------------------------------------------------------ ++ bool save_sections( std::ostream& stream ) ++ { ++ for ( unsigned int i = 0; i < sections_.size(); ++i ) { ++ section* sec = sections_.at( i ); ++ ++ std::streampos headerPosition = ++ (std::streamoff)header->get_sections_offset() + ++ (std::streampos)header->get_section_entry_size() * ++ sec->get_index(); ++ ++ sec->save( stream, headerPosition, sec->get_offset() ); ++ } ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool save_segments( std::ostream& stream ) ++ { ++ for ( unsigned int i = 0; i < segments_.size(); ++i ) { ++ segment* seg = segments_.at( i ); ++ ++ std::streampos headerPosition = ++ header->get_segments_offset() + ++ (std::streampos)header->get_segment_entry_size() * ++ seg->get_index(); ++ ++ seg->save( stream, headerPosition, seg->get_offset() ); ++ } ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_section_without_segment( unsigned int section_index ) ++ { ++ bool found = false; ++ ++ for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) { ++ for ( unsigned int k = 0; ++ !found && ( k < segments[j]->get_sections_num() ); ++k ) { ++ found = segments[j]->get_section_index_at( k ) == section_index; ++ } ++ } ++ ++ return !found; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool is_subsequence_of( segment* seg1, segment* seg2 ) ++ { ++ // Return 'true' if sections of seg1 are a subset of sections in seg2 ++ const std::vector<Elf_Half>& sections1 = seg1->get_sections(); ++ const std::vector<Elf_Half>& sections2 = seg2->get_sections(); ++ ++ bool found = false; ++ if ( sections1.size() < sections2.size() ) { ++ found = std::includes( sections2.begin(), sections2.end(), ++ sections1.begin(), sections1.end() ); ++ } ++ ++ return found; ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*> get_ordered_segments() ++ { ++ std::vector<segment*> res; ++ std::deque<segment*> worklist; ++ ++ res.reserve( segments.size() ); ++ std::copy( segments_.begin(), segments_.end(), ++ std::back_inserter( worklist ) ); ++ ++ // Bring the segments which start at address 0 to the front ++ size_t nextSlot = 0; ++ for ( size_t i = 0; i < worklist.size(); ++i ) { ++ if ( i != nextSlot && worklist[i]->is_offset_initialized() && ++ worklist[i]->get_offset() == 0 ) { ++ if ( worklist[nextSlot]->get_offset() == 0 ) { ++ ++nextSlot; ++ } ++ std::swap( worklist[i], worklist[nextSlot] ); ++ ++nextSlot; ++ } ++ } ++ ++ while ( !worklist.empty() ) { ++ segment* seg = worklist.front(); ++ worklist.pop_front(); ++ ++ size_t i = 0; ++ for ( ; i < worklist.size(); ++i ) { ++ if ( is_subsequence_of( seg, worklist[i] ) ) { ++ break; ++ } ++ } ++ ++ if ( i < worklist.size() ) ++ worklist.push_back( seg ); ++ else ++ res.push_back( seg ); ++ } ++ ++ return res; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_sections_without_segments() ++ { ++ for ( unsigned int i = 0; i < sections_.size(); ++i ) { ++ if ( is_section_without_segment( i ) ) { ++ section* sec = sections_[i]; ++ ++ Elf_Xword section_align = sec->get_addr_align(); ++ if ( section_align > 1 && ++ current_file_pos % section_align != 0 ) { ++ current_file_pos += ++ section_align - current_file_pos % section_align; ++ } ++ ++ if ( 0 != sec->get_index() ) ++ sec->set_offset( current_file_pos ); ++ ++ if ( SHT_NOBITS != sec->get_type() && ++ SHT_NULL != sec->get_type() ) { ++ current_file_pos += sec->get_size(); ++ } ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void calc_segment_alignment() ++ { ++ for ( std::vector<segment*>::iterator s = segments_.begin(); ++ s != segments_.end(); ++s ) { ++ segment* seg = *s; ++ for ( int i = 0; i < seg->get_sections_num(); ++i ) { ++ section* sect = sections_[seg->get_section_index_at( i )]; ++ if ( sect->get_addr_align() > seg->get_align() ) { ++ seg->set_align( sect->get_addr_align() ); ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_segments_and_their_sections() ++ { ++ std::vector<segment*> worklist; ++ std::vector<bool> section_generated( sections.size(), false ); ++ ++ // Get segments in a order in where segments which contain a ++ // sub sequence of other segments are located at the end ++ worklist = get_ordered_segments(); ++ ++ for ( unsigned int i = 0; i < worklist.size(); ++i ) { ++ Elf_Xword segment_memory = 0; ++ Elf_Xword segment_filesize = 0; ++ Elf_Xword seg_start_pos = current_file_pos; ++ segment* seg = worklist[i]; ++ ++ // Special case: PHDR segment ++ // This segment contains the program headers but no sections ++ if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) { ++ seg_start_pos = header->get_segments_offset(); ++ segment_memory = segment_filesize = ++ header->get_segment_entry_size() * ++ (Elf_Xword)header->get_segments_num(); ++ } ++ // Special case: ++ else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) { ++ seg_start_pos = 0; ++ if ( seg->get_sections_num() ) { ++ segment_memory = segment_filesize = current_file_pos; ++ } ++ } ++ // New segments with not generated sections ++ // have to be aligned ++ else if ( seg->get_sections_num() && ++ !section_generated[seg->get_section_index_at( 0 )] ) { ++ Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1; ++ Elf64_Off cur_page_alignment = current_file_pos % align; ++ Elf64_Off req_page_alignment = ++ seg->get_virtual_address() % align; ++ Elf64_Off error = req_page_alignment - cur_page_alignment; ++ ++ current_file_pos += ( seg->get_align() + error ) % align; ++ seg_start_pos = current_file_pos; ++ } ++ else if ( seg->get_sections_num() ) { ++ seg_start_pos = ++ sections[seg->get_section_index_at( 0 )]->get_offset(); ++ } ++ ++ // Write segment's data ++ for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) { ++ Elf_Half index = seg->get_section_index_at( j ); ++ ++ section* sec = sections[index]; ++ ++ // The NULL section is always generated ++ if ( SHT_NULL == sec->get_type() ) { ++ section_generated[index] = true; ++ continue; ++ } ++ ++ Elf_Xword secAlign = 0; ++ // Fix up the alignment ++ if ( !section_generated[index] && ++ sec->is_address_initialized() && ++ SHT_NOBITS != sec->get_type() && ++ SHT_NULL != sec->get_type() && 0 != sec->get_size() ) { ++ // Align the sections based on the virtual addresses ++ // when possible (this is what matters for execution) ++ Elf64_Off req_offset = ++ sec->get_address() - seg->get_virtual_address(); ++ Elf64_Off cur_offset = current_file_pos - seg_start_pos; ++ if ( req_offset < cur_offset ) { ++ // something has gone awfully wrong, abort! ++ // secAlign would turn out negative, seeking backwards and overwriting previous data ++ return false; ++ } ++ secAlign = req_offset - cur_offset; ++ } ++ else if ( !section_generated[index] && ++ !sec->is_address_initialized() ) { ++ // If no address has been specified then only the section ++ // alignment constraint has to be matched ++ Elf_Xword align = sec->get_addr_align(); ++ if ( align == 0 ) { ++ align = 1; ++ } ++ Elf64_Off error = current_file_pos % align; ++ secAlign = ( align - error ) % align; ++ } ++ else if ( section_generated[index] ) { ++ // Alignment for already generated sections ++ secAlign = ++ sec->get_offset() - seg_start_pos - segment_filesize; ++ } ++ ++ // Determine the segment file and memory sizes ++ // Special case .tbss section (NOBITS) in non TLS segment ++ if ( ( sec->get_flags() & SHF_ALLOC ) && ++ !( ( sec->get_flags() & SHF_TLS ) && ++ ( seg->get_type() != PT_TLS ) && ++ ( SHT_NOBITS == sec->get_type() ) ) ) ++ segment_memory += sec->get_size() + secAlign; ++ ++ if ( SHT_NOBITS != sec->get_type() ) ++ segment_filesize += sec->get_size() + secAlign; ++ ++ // Nothing to be done when generating nested segments ++ if ( section_generated[index] ) { ++ continue; ++ } ++ ++ current_file_pos += secAlign; ++ ++ // Set the section addresses when missing ++ if ( !sec->is_address_initialized() ) ++ sec->set_address( seg->get_virtual_address() + ++ current_file_pos - seg_start_pos ); ++ ++ if ( 0 != sec->get_index() ) ++ sec->set_offset( current_file_pos ); ++ ++ if ( SHT_NOBITS != sec->get_type() ) ++ current_file_pos += sec->get_size(); ++ ++ section_generated[index] = true; ++ } ++ ++ seg->set_file_size( segment_filesize ); ++ ++ // If we already have a memory size from loading an elf file (value > 0), ++ // it must not shrink! ++ // Memory size may be bigger than file size and it is the loader's job to do something ++ // with the surplus bytes in memory, like initializing them with a defined value. ++ if ( seg->get_memory_size() < segment_memory ) { ++ seg->set_memory_size( segment_memory ); ++ } ++ ++ seg->set_offset( seg_start_pos ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool layout_section_table() ++ { ++ // Simply place the section table at the end for now ++ Elf64_Off alignmentError = current_file_pos % 4; ++ current_file_pos += ( 4 - alignmentError ) % 4; ++ header->set_sections_offset( current_file_pos ); ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ public: ++ friend class Sections; ++ class Sections ++ { ++ public: ++ //------------------------------------------------------------------------------ ++ Sections( elfio* parent_ ) : parent( parent_ ) {} ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half size() const { return (Elf_Half)parent->sections_.size(); } ++ ++ //------------------------------------------------------------------------------ ++ section* operator[]( unsigned int index ) const ++ { ++ section* sec = 0; ++ ++ if ( index < parent->sections_.size() ) { ++ sec = parent->sections_[index]; ++ } ++ ++ return sec; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* operator[]( const std::string& name ) const ++ { ++ section* sec = 0; ++ ++ std::vector<section*>::const_iterator it; ++ for ( it = parent->sections_.begin(); it != parent->sections_.end(); ++ ++it ) { ++ if ( ( *it )->get_name() == name ) { ++ sec = *it; ++ break; ++ } ++ } ++ ++ return sec; ++ } ++ ++ //------------------------------------------------------------------------------ ++ section* add( const std::string& name ) ++ { ++ section* new_section = parent->create_section(); ++ new_section->set_name( name ); ++ ++ Elf_Half str_index = parent->get_section_name_str_index(); ++ section* string_table( parent->sections_[str_index] ); ++ string_section_accessor str_writer( string_table ); ++ Elf_Word pos = str_writer.add_string( name ); ++ new_section->set_name_string_offset( pos ); ++ ++ return new_section; ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::iterator begin() ++ { ++ return parent->sections_.begin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::iterator end() ++ { ++ return parent->sections_.end(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::const_iterator begin() const ++ { ++ return parent->sections_.cbegin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<section*>::const_iterator end() const ++ { ++ return parent->sections_.cend(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elfio* parent; ++ } sections; ++ ++ //------------------------------------------------------------------------------ ++ public: ++ friend class Segments; ++ class Segments ++ { ++ public: ++ //------------------------------------------------------------------------------ ++ Segments( elfio* parent_ ) : parent( parent_ ) {} ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half size() const { return (Elf_Half)parent->segments_.size(); } ++ ++ //------------------------------------------------------------------------------ ++ segment* operator[]( unsigned int index ) const ++ { ++ return parent->segments_[index]; ++ } ++ ++ //------------------------------------------------------------------------------ ++ segment* add() { return parent->create_segment(); } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::iterator begin() ++ { ++ return parent->segments_.begin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::iterator end() ++ { ++ return parent->segments_.end(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::const_iterator begin() const ++ { ++ return parent->segments_.cbegin(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ std::vector<segment*>::const_iterator end() const ++ { ++ return parent->segments_.cend(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elfio* parent; ++ } segments; ++ ++ //------------------------------------------------------------------------------ ++ private: ++ elf_header* header; ++ std::vector<section*> sections_; ++ std::vector<segment*> segments_; ++ endianess_convertor convertor; ++ ++ Elf_Xword current_file_pos; ++}; ++ ++} // namespace ELFIO ++ ++ ++/*** Start of inlined file: elfio_symbols.hpp ***/ ++#ifndef ELFIO_SYMBOLS_HPP ++#define ELFIO_SYMBOLS_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class symbol_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ symbol_section_accessor_template( const elfio& elf_file_, ++ S* symbol_section_ ) ++ : elf_file( elf_file_ ), symbol_section( symbol_section_ ) ++ { ++ find_hash_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_symbols_num() const ++ { ++ Elf_Xword nRet = 0; ++ if ( 0 != symbol_section->get_entry_size() ) { ++ nRet = ++ symbol_section->get_size() / symbol_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( Elf_Xword index, ++ std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ ret = generic_get_symbol<Elf32_Sym>( index, name, value, size, bind, ++ type, section_index, other ); ++ } ++ else { ++ ret = generic_get_symbol<Elf64_Sym>( index, name, value, size, bind, ++ type, section_index, other ); ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( const std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( 0 != get_hash_table_index() ) { ++ Elf_Word nbucket = *(const Elf_Word*)hash_section->get_data(); ++ Elf_Word nchain = *(const Elf_Word*)( hash_section->get_data() + ++ sizeof( Elf_Word ) ); ++ Elf_Word val = elf_hash( (const unsigned char*)name.c_str() ); ++ Elf_Word y = *(const Elf_Word*)( hash_section->get_data() + ++ ( 2 + val % nbucket ) * ++ sizeof( Elf_Word ) ); ++ std::string str; ++ get_symbol( y, str, value, size, bind, type, section_index, other ); ++ while ( str != name && STN_UNDEF != y && y < nchain ) { ++ y = *(const Elf_Word*)( hash_section->get_data() + ++ ( 2 + nbucket + y ) * ++ sizeof( Elf_Word ) ); ++ get_symbol( y, str, value, size, bind, type, section_index, ++ other ); ++ } ++ if ( str == name ) { ++ ret = true; ++ } ++ } ++ else { ++ for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) { ++ std::string symbol_name; ++ if ( get_symbol( i, symbol_name, value, size, bind, type, ++ section_index, other ) ) { ++ if ( symbol_name == name ) { ++ ret = true; ++ } ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_symbol( const Elf64_Addr& value, ++ std::string& name, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ Elf_Xword idx = 0; ++ bool match = false; ++ Elf64_Addr v = 0; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ match = generic_search_symbols<Elf32_Sym>( ++ [&]( const Elf32_Sym* sym ) { ++ return convertor( sym->st_value ) == value; ++ }, ++ idx ); ++ } ++ else { ++ match = generic_search_symbols<Elf64_Sym>( ++ [&]( const Elf64_Sym* sym ) { ++ return convertor( sym->st_value ) == value; ++ }, ++ idx ); ++ } ++ ++ if ( match ) { ++ return get_symbol( idx, name, v, size, bind, type, section_index, ++ other ); ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ Elf_Word nRet; ++ ++ if ( symbol_section->get_size() == 0 ) { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_add_symbol<Elf32_Sym>( 0, 0, 0, 0, 0, 0 ); ++ } ++ else { ++ nRet = generic_add_symbol<Elf64_Sym>( 0, 0, 0, 0, 0, 0 ); ++ } ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info, ++ other, shndx ); ++ } ++ else { ++ nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info, ++ other, shndx ); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, ++ shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( string_section_accessor& pStrWriter, ++ const char* str, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ Elf_Word index = pStrWriter.add_string( str ); ++ return add_symbol( index, value, size, info, other, shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_symbol( string_section_accessor& pStrWriter, ++ const char* str, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ return add_symbol( pStrWriter, str, value, size, ++ ELF_ST_INFO( bind, type ), other, shndx ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword arrange_local_symbols( ++ std::function<void( Elf_Xword first, Elf_Xword second )> func = ++ nullptr ) ++ { ++ int nRet = 0; ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ nRet = generic_arrange_local_symbols<Elf32_Sym>( func ); ++ } ++ else { ++ nRet = generic_arrange_local_symbols<Elf64_Sym>( func ); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ void find_hash_section() ++ { ++ hash_section = 0; ++ hash_section_index = 0; ++ Elf_Half nSecNo = elf_file.sections.size(); ++ for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) { ++ const section* sec = elf_file.sections[i]; ++ if ( sec->get_link() == symbol_section->get_index() ) { ++ hash_section = sec; ++ hash_section_index = i; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_string_table_index() const ++ { ++ return (Elf_Half)symbol_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Half get_hash_table_index() const { return hash_section_index; } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> const T* generic_get_symbol_ptr( Elf_Xword index ) const ++ { ++ if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { ++ const T* pSym = reinterpret_cast<const T*>( ++ symbol_section->get_data() + ++ index * symbol_section->get_entry_size() ); ++ ++ return pSym; ++ } ++ ++ return nullptr; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ bool generic_search_symbols( std::function<bool( const T* )> match, ++ Elf_Xword& idx ) const ++ { ++ for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) { ++ const T* symPtr = generic_get_symbol_ptr<T>( i ); ++ ++ if ( symPtr == nullptr ) ++ return false; ++ ++ if ( match( symPtr ) ) { ++ idx = i; ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ bool generic_get_symbol( Elf_Xword index, ++ std::string& name, ++ Elf64_Addr& value, ++ Elf_Xword& size, ++ unsigned char& bind, ++ unsigned char& type, ++ Elf_Half& section_index, ++ unsigned char& other ) const ++ { ++ bool ret = false; ++ ++ if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) { ++ const T* pSym = reinterpret_cast<const T*>( ++ symbol_section->get_data() + ++ index * symbol_section->get_entry_size() ); ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ section* string_section = ++ elf_file.sections[get_string_table_index()]; ++ string_section_accessor str_reader( string_section ); ++ const char* pStr = ++ str_reader.get_string( convertor( pSym->st_name ) ); ++ if ( 0 != pStr ) { ++ name = pStr; ++ } ++ value = convertor( pSym->st_value ); ++ size = convertor( pSym->st_size ); ++ bind = ELF_ST_BIND( pSym->st_info ); ++ type = ELF_ST_TYPE( pSym->st_info ); ++ section_index = convertor( pSym->st_shndx ); ++ other = pSym->st_other; ++ ++ ret = true; ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ Elf_Word generic_add_symbol( Elf_Word name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char info, ++ unsigned char other, ++ Elf_Half shndx ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.st_name = convertor( name ); ++ entry.st_value = value; ++ entry.st_value = convertor( entry.st_value ); ++ entry.st_size = size; ++ entry.st_size = convertor( entry.st_size ); ++ entry.st_info = convertor( info ); ++ entry.st_other = convertor( other ); ++ entry.st_shndx = convertor( shndx ); ++ ++ symbol_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ ++ Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1; ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ Elf_Xword generic_arrange_local_symbols( ++ std::function<void( Elf_Xword first, Elf_Xword second )> func ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ const Elf_Xword size = symbol_section->get_entry_size(); ++ ++ Elf_Xword first_not_local = ++ 1; // Skip the first entry. It is always NOTYPE ++ Elf_Xword current = 0; ++ Elf_Xword count = get_symbols_num(); ++ ++ while ( true ) { ++ T* p1 = nullptr; ++ T* p2 = nullptr; ++ ++ while ( first_not_local < count ) { ++ p1 = const_cast<T*>( ++ generic_get_symbol_ptr<T>( first_not_local ) ); ++ if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL ) ++ break; ++ ++first_not_local; ++ } ++ ++ current = first_not_local + 1; ++ while ( current < count ) { ++ p2 = const_cast<T*>( generic_get_symbol_ptr<T>( current ) ); ++ if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL ) ++ break; ++ ++current; ++ } ++ ++ if ( first_not_local < count && current < count ) { ++ if ( func ) ++ func( first_not_local, current ); ++ ++ // Swap the symbols ++ T tmp; ++ std::copy( p1, p1 + 1, &tmp ); ++ std::copy( p2, p2 + 1, p1 ); ++ std::copy( &tmp, &tmp + 1, p2 ); ++ } ++ else { ++ // Update 'info' field of the section ++ symbol_section->set_info( first_not_local ); ++ break; ++ } ++ } ++ ++ // Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1; ++ ++ return first_not_local; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* symbol_section; ++ Elf_Half hash_section_index; ++ const section* hash_section; ++}; ++ ++using symbol_section_accessor = symbol_section_accessor_template<section>; ++using const_symbol_section_accessor = ++ symbol_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_SYMBOLS_HPP ++ ++/*** End of inlined file: elfio_symbols.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_note.hpp ***/ ++#ifndef ELFIO_NOTE_HPP ++#define ELFIO_NOTE_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++// There are discrepancies in documentations. SCO documentation ++// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section) ++// requires 8 byte entries alignment for 64-bit ELF file, ++// but Oracle's definition uses the same structure ++// for 32-bit and 64-bit formats. ++// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html) ++// ++// It looks like EM_X86_64 Linux implementation is similar to Oracle's ++// definition. Therefore, the same alignment works for both formats ++//------------------------------------------------------------------------------ ++ ++//------------------------------------------------------------------------------ ++template <class S> class note_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ note_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), note_section( section_ ) ++ { ++ process_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word get_notes_num() const ++ { ++ return (Elf_Word)note_start_positions.size(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_note( Elf_Word index, ++ Elf_Word& type, ++ std::string& name, ++ void*& desc, ++ Elf_Word& descSize ) const ++ { ++ if ( index >= note_section->get_size() ) { ++ return false; ++ } ++ ++ const char* pData = ++ note_section->get_data() + note_start_positions[index]; ++ int align = sizeof( Elf_Word ); ++ ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ type = convertor( *(const Elf_Word*)( pData + 2 * align ) ); ++ Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) ); ++ descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) ); ++ ++ Elf_Xword max_name_size = ++ note_section->get_size() - note_start_positions[index]; ++ if ( namesz < 1 || namesz > max_name_size || ++ (Elf_Xword)namesz + descSize > max_name_size ) { ++ return false; ++ } ++ name.assign( pData + 3 * align, namesz - 1 ); ++ if ( 0 == descSize ) { ++ desc = 0; ++ } ++ else { ++ desc = ++ const_cast<char*>( pData + 3 * align + ++ ( ( namesz + align - 1 ) / align ) * align ); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_note( Elf_Word type, ++ const std::string& name, ++ const void* desc, ++ Elf_Word descSize ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ int align = sizeof( Elf_Word ); ++ Elf_Word nameLen = (Elf_Word)name.size() + 1; ++ Elf_Word nameLenConv = convertor( nameLen ); ++ std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align ); ++ Elf_Word descSizeConv = convertor( descSize ); ++ ++ buffer.append( reinterpret_cast<char*>( &descSizeConv ), align ); ++ type = convertor( type ); ++ buffer.append( reinterpret_cast<char*>( &type ), align ); ++ buffer.append( name ); ++ buffer.append( 1, '\x00' ); ++ const char pad[] = { '\0', '\0', '\0', '\0' }; ++ if ( nameLen % align != 0 ) { ++ buffer.append( pad, align - nameLen % align ); ++ } ++ if ( desc != 0 && descSize != 0 ) { ++ buffer.append( reinterpret_cast<const char*>( desc ), descSize ); ++ if ( descSize % align != 0 ) { ++ buffer.append( pad, align - descSize % align ); ++ } ++ } ++ ++ note_start_positions.push_back( note_section->get_size() ); ++ note_section->append_data( buffer ); ++ } ++ ++ private: ++ //------------------------------------------------------------------------------ ++ void process_section() ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ const char* data = note_section->get_data(); ++ Elf_Xword size = note_section->get_size(); ++ Elf_Xword current = 0; ++ ++ note_start_positions.clear(); ++ ++ // Is it empty? ++ if ( 0 == data || 0 == size ) { ++ return; ++ } ++ ++ Elf_Word align = sizeof( Elf_Word ); ++ while ( current + (Elf_Xword)3 * align <= size ) { ++ note_start_positions.push_back( current ); ++ Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) ); ++ Elf_Word descsz = convertor( ++ *(const Elf_Word*)( data + current + sizeof( namesz ) ) ); ++ ++ current += (Elf_Xword)3 * sizeof( Elf_Word ) + ++ ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align + ++ ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* note_section; ++ std::vector<Elf_Xword> note_start_positions; ++}; ++ ++using note_section_accessor = note_section_accessor_template<section>; ++using const_note_section_accessor = ++ note_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_NOTE_HPP ++ ++/*** End of inlined file: elfio_note.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_relocation.hpp ***/ ++#ifndef ELFIO_RELOCATION_HPP ++#define ELFIO_RELOCATION_HPP ++ ++namespace ELFIO { ++ ++template <typename T> struct get_sym_and_type; ++template <> struct get_sym_and_type<Elf32_Rel> ++{ ++ static int get_r_sym( Elf_Xword info ) ++ { ++ return ELF32_R_SYM( (Elf_Word)info ); ++ } ++ static int get_r_type( Elf_Xword info ) ++ { ++ return ELF32_R_TYPE( (Elf_Word)info ); ++ } ++}; ++template <> struct get_sym_and_type<Elf32_Rela> ++{ ++ static int get_r_sym( Elf_Xword info ) ++ { ++ return ELF32_R_SYM( (Elf_Word)info ); ++ } ++ static int get_r_type( Elf_Xword info ) ++ { ++ return ELF32_R_TYPE( (Elf_Word)info ); ++ } ++}; ++template <> struct get_sym_and_type<Elf64_Rel> ++{ ++ static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } ++ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } ++}; ++template <> struct get_sym_and_type<Elf64_Rela> ++{ ++ static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); } ++ static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); } ++}; ++ ++//------------------------------------------------------------------------------ ++template <class S> class relocation_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ relocation_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), relocation_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_entries_num() const ++ { ++ Elf_Xword nRet = 0; ++ ++ if ( 0 != relocation_section->get_entry_size() ) { ++ nRet = relocation_section->get_size() / ++ relocation_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_get_entry_rel<Elf32_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_get_entry_rela<Elf32_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ else { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_get_entry_rel<Elf64_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_get_entry_rela<Elf64_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf64_Addr& symbolValue, ++ std::string& symbolName, ++ Elf_Word& type, ++ Elf_Sxword& addend, ++ Elf_Sxword& calcValue ) const ++ { ++ // Do regular job ++ Elf_Word symbol; ++ bool ret = get_entry( index, offset, symbol, type, addend ); ++ ++ // Find the symbol ++ Elf_Xword size; ++ unsigned char bind; ++ unsigned char symbolType; ++ Elf_Half section; ++ unsigned char other; ++ ++ symbol_section_accessor symbols( ++ elf_file, elf_file.sections[get_symbol_table_index()] ); ++ ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size, ++ bind, symbolType, section, other ); ++ ++ if ( ret ) { // Was it successful? ++ switch ( type ) { ++ case R_386_NONE: // none ++ calcValue = 0; ++ break; ++ case R_386_32: // S + A ++ calcValue = symbolValue + addend; ++ break; ++ case R_386_PC32: // S + A - P ++ calcValue = symbolValue + addend - offset; ++ break; ++ case R_386_GOT32: // G + A - P ++ calcValue = 0; ++ break; ++ case R_386_PLT32: // L + A - P ++ calcValue = 0; ++ break; ++ case R_386_COPY: // none ++ calcValue = 0; ++ break; ++ case R_386_GLOB_DAT: // S ++ case R_386_JMP_SLOT: // S ++ calcValue = symbolValue; ++ break; ++ case R_386_RELATIVE: // B + A ++ calcValue = addend; ++ break; ++ case R_386_GOTOFF: // S + A - GOT ++ calcValue = 0; ++ break; ++ case R_386_GOTPC: // GOT + A - P ++ calcValue = 0; ++ break; ++ default: // Not recognized symbol! ++ calcValue = 0; ++ break; ++ } ++ } ++ ++ return ret; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool set_entry( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword addend ) ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_set_entry_rel<Elf32_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_set_entry_rela<Elf32_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ else { ++ if ( SHT_REL == relocation_section->get_type() ) { ++ generic_set_entry_rel<Elf64_Rel>( index, offset, symbol, type, ++ addend ); ++ } ++ else if ( SHT_RELA == relocation_section->get_type() ) { ++ generic_set_entry_rela<Elf64_Rela>( index, offset, symbol, type, ++ addend ); ++ } ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Xword info ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Rel>( offset, info ); ++ } ++ else { ++ generic_add_entry<Elf64_Rel>( offset, info ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type ) ++ { ++ Elf_Xword info; ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ ++ add_entry( offset, info ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Rela>( offset, info, addend ); ++ } ++ else { ++ generic_add_entry<Elf64_Rela>( offset, info, addend ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf64_Addr offset, ++ Elf_Word symbol, ++ unsigned char type, ++ Elf_Sxword addend ) ++ { ++ Elf_Xword info; ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ ++ add_entry( offset, info, addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( string_section_accessor str_writer, ++ const char* str, ++ symbol_section_accessor sym_writer, ++ Elf64_Addr value, ++ Elf_Word size, ++ unsigned char sym_info, ++ unsigned char other, ++ Elf_Half shndx, ++ Elf64_Addr offset, ++ unsigned char type ) ++ { ++ Elf_Word str_index = str_writer.add_string( str ); ++ Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size, ++ sym_info, other, shndx ); ++ add_entry( offset, sym_index, type ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ void swap_symbols( Elf_Xword first, Elf_Xword second ) ++ { ++ Elf64_Addr offset; ++ Elf_Word symbol; ++ Elf_Word rtype; ++ Elf_Sxword addend; ++ for ( Elf_Word i = 0; i < get_entries_num(); i++ ) { ++ get_entry( i, offset, symbol, rtype, addend ); ++ if ( symbol == first ) { ++ set_entry( i, offset, (Elf_Word)second, rtype, addend ); ++ } ++ if ( symbol == second ) { ++ set_entry( i, offset, (Elf_Word)first, rtype, addend ); ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ Elf_Half get_symbol_table_index() const ++ { ++ return (Elf_Half)relocation_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_rel( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ); ++ offset = convertor( pEntry->r_offset ); ++ Elf_Xword tmp = convertor( pEntry->r_info ); ++ symbol = get_sym_and_type<T>::get_r_sym( tmp ); ++ type = get_sym_and_type<T>::get_r_type( tmp ); ++ addend = 0; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_rela( Elf_Xword index, ++ Elf64_Addr& offset, ++ Elf_Word& symbol, ++ Elf_Word& type, ++ Elf_Sxword& addend ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ); ++ offset = convertor( pEntry->r_offset ); ++ Elf_Xword tmp = convertor( pEntry->r_info ); ++ symbol = get_sym_and_type<T>::get_r_sym( tmp ); ++ type = get_sym_and_type<T>::get_r_type( tmp ); ++ addend = convertor( pEntry->r_addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_set_entry_rel( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T* pEntry = const_cast<T*>( reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ) ); ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ pEntry->r_offset = offset; ++ pEntry->r_offset = convertor( pEntry->r_offset ); ++ pEntry->r_info = convertor( pEntry->r_info ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_set_entry_rela( Elf_Xword index, ++ Elf64_Addr offset, ++ Elf_Word symbol, ++ Elf_Word type, ++ Elf_Sxword addend ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T* pEntry = const_cast<T*>( reinterpret_cast<const T*>( ++ relocation_section->get_data() + ++ index * relocation_section->get_entry_size() ) ); ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ else { ++ pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type ); ++ } ++ pEntry->r_offset = offset; ++ pEntry->r_addend = addend; ++ pEntry->r_offset = convertor( pEntry->r_offset ); ++ pEntry->r_info = convertor( pEntry->r_info ); ++ pEntry->r_addend = convertor( pEntry->r_addend ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_add_entry( Elf64_Addr offset, Elf_Xword info ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.r_offset = offset; ++ entry.r_info = info; ++ entry.r_offset = convertor( entry.r_offset ); ++ entry.r_info = convertor( entry.r_info ); ++ ++ relocation_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void ++ generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ entry.r_offset = offset; ++ entry.r_info = info; ++ entry.r_addend = addend; ++ entry.r_offset = convertor( entry.r_offset ); ++ entry.r_info = convertor( entry.r_info ); ++ entry.r_addend = convertor( entry.r_addend ); ++ ++ relocation_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* relocation_section; ++}; ++ ++using relocation_section_accessor = ++ relocation_section_accessor_template<section>; ++using const_relocation_section_accessor = ++ relocation_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_RELOCATION_HPP ++ ++/*** End of inlined file: elfio_relocation.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_dynamic.hpp ***/ ++#ifndef ELFIO_DYNAMIC_HPP ++#define ELFIO_DYNAMIC_HPP ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class dynamic_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ dynamic_section_accessor_template( const elfio& elf_file_, S* section_ ) ++ : elf_file( elf_file_ ), dynamic_section( section_ ) ++ { ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Xword get_entries_num() const ++ { ++ Elf_Xword nRet = 0; ++ ++ if ( 0 != dynamic_section->get_entry_size() ) { ++ nRet = ++ dynamic_section->get_size() / dynamic_section->get_entry_size(); ++ } ++ ++ return nRet; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_entry( Elf_Xword index, ++ Elf_Xword& tag, ++ Elf_Xword& value, ++ std::string& str ) const ++ { ++ if ( index >= get_entries_num() ) { // Is index valid ++ return false; ++ } ++ ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_get_entry_dyn<Elf32_Dyn>( index, tag, value ); ++ } ++ else { ++ generic_get_entry_dyn<Elf64_Dyn>( index, tag, value ); ++ } ++ ++ // If the tag may have a string table reference, prepare the string ++ if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || ++ tag == DT_RUNPATH ) { ++ string_section_accessor strsec = ++ elf_file.sections[get_string_table_index()]; ++ const char* result = strsec.get_string( value ); ++ if ( 0 == result ) { ++ str.clear(); ++ return false; ++ } ++ str = result; ++ } ++ else { ++ str.clear(); ++ } ++ ++ return true; ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf_Xword tag, Elf_Xword value ) ++ { ++ if ( elf_file.get_class() == ELFCLASS32 ) { ++ generic_add_entry<Elf32_Dyn>( tag, value ); ++ } ++ else { ++ generic_add_entry<Elf64_Dyn>( tag, value ); ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ void add_entry( Elf_Xword tag, const std::string& str ) ++ { ++ string_section_accessor strsec = ++ elf_file.sections[get_string_table_index()]; ++ Elf_Xword value = strsec.add_string( str ); ++ add_entry( tag, value ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ //------------------------------------------------------------------------------ ++ Elf_Half get_string_table_index() const ++ { ++ return (Elf_Half)dynamic_section->get_link(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> ++ void generic_get_entry_dyn( Elf_Xword index, ++ Elf_Xword& tag, ++ Elf_Xword& value ) const ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ // Check unusual case when dynamic section has no data ++ if ( dynamic_section->get_data() == 0 || ++ ( index + 1 ) * dynamic_section->get_entry_size() > ++ dynamic_section->get_size() ) { ++ tag = DT_NULL; ++ value = 0; ++ return; ++ } ++ ++ const T* pEntry = reinterpret_cast<const T*>( ++ dynamic_section->get_data() + ++ index * dynamic_section->get_entry_size() ); ++ tag = convertor( pEntry->d_tag ); ++ switch ( tag ) { ++ case DT_NULL: ++ case DT_SYMBOLIC: ++ case DT_TEXTREL: ++ case DT_BIND_NOW: ++ value = 0; ++ break; ++ case DT_NEEDED: ++ case DT_PLTRELSZ: ++ case DT_RELASZ: ++ case DT_RELAENT: ++ case DT_STRSZ: ++ case DT_SYMENT: ++ case DT_SONAME: ++ case DT_RPATH: ++ case DT_RELSZ: ++ case DT_RELENT: ++ case DT_PLTREL: ++ case DT_INIT_ARRAYSZ: ++ case DT_FINI_ARRAYSZ: ++ case DT_RUNPATH: ++ case DT_FLAGS: ++ case DT_PREINIT_ARRAYSZ: ++ value = convertor( pEntry->d_un.d_val ); ++ break; ++ case DT_PLTGOT: ++ case DT_HASH: ++ case DT_STRTAB: ++ case DT_SYMTAB: ++ case DT_RELA: ++ case DT_INIT: ++ case DT_FINI: ++ case DT_REL: ++ case DT_DEBUG: ++ case DT_JMPREL: ++ case DT_INIT_ARRAY: ++ case DT_FINI_ARRAY: ++ case DT_PREINIT_ARRAY: ++ default: ++ value = convertor( pEntry->d_un.d_ptr ); ++ break; ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <class T> void generic_add_entry( Elf_Xword tag, Elf_Xword value ) ++ { ++ const endianess_convertor& convertor = elf_file.get_convertor(); ++ ++ T entry; ++ ++ switch ( tag ) { ++ case DT_NULL: ++ case DT_SYMBOLIC: ++ case DT_TEXTREL: ++ case DT_BIND_NOW: ++ value = 0; ++ case DT_NEEDED: ++ case DT_PLTRELSZ: ++ case DT_RELASZ: ++ case DT_RELAENT: ++ case DT_STRSZ: ++ case DT_SYMENT: ++ case DT_SONAME: ++ case DT_RPATH: ++ case DT_RELSZ: ++ case DT_RELENT: ++ case DT_PLTREL: ++ case DT_INIT_ARRAYSZ: ++ case DT_FINI_ARRAYSZ: ++ case DT_RUNPATH: ++ case DT_FLAGS: ++ case DT_PREINIT_ARRAYSZ: ++ entry.d_un.d_val = convertor( value ); ++ break; ++ case DT_PLTGOT: ++ case DT_HASH: ++ case DT_STRTAB: ++ case DT_SYMTAB: ++ case DT_RELA: ++ case DT_INIT: ++ case DT_FINI: ++ case DT_REL: ++ case DT_DEBUG: ++ case DT_JMPREL: ++ case DT_INIT_ARRAY: ++ case DT_FINI_ARRAY: ++ case DT_PREINIT_ARRAY: ++ default: ++ entry.d_un.d_ptr = convertor( value ); ++ break; ++ } ++ ++ entry.d_tag = convertor( tag ); ++ ++ dynamic_section->append_data( reinterpret_cast<char*>( &entry ), ++ sizeof( entry ) ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ const elfio& elf_file; ++ S* dynamic_section; ++}; ++ ++using dynamic_section_accessor = dynamic_section_accessor_template<section>; ++using const_dynamic_section_accessor = ++ dynamic_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_DYNAMIC_HPP ++ ++/*** End of inlined file: elfio_dynamic.hpp ***/ ++ ++ ++/*** Start of inlined file: elfio_modinfo.hpp ***/ ++#ifndef ELFIO_MODINFO_HPP ++#define ELFIO_MODINFO_HPP ++ ++#include <string> ++#include <vector> ++ ++namespace ELFIO { ++ ++//------------------------------------------------------------------------------ ++template <class S> class modinfo_section_accessor_template ++{ ++ public: ++ //------------------------------------------------------------------------------ ++ modinfo_section_accessor_template( S* section_ ) ++ : modinfo_section( section_ ) ++ { ++ process_section(); ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); } ++ ++ //------------------------------------------------------------------------------ ++ bool ++ get_attribute( Elf_Word no, std::string& field, std::string& value ) const ++ { ++ if ( no < content.size() ) { ++ field = content[no].first; ++ value = content[no].second; ++ return true; ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ bool get_attribute( std::string field_name, std::string& value ) const ++ { ++ for ( auto i = content.begin(); i != content.end(); i++ ) { ++ if ( field_name == i->first ) { ++ value = i->second; ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ //------------------------------------------------------------------------------ ++ Elf_Word add_attribute( std::string field, std::string value ) ++ { ++ Elf_Word current_position = 0; ++ ++ if ( modinfo_section ) { ++ // Strings are addeded to the end of the current section data ++ current_position = (Elf_Word)modinfo_section->get_size(); ++ ++ std::string attribute = field + "=" + value; ++ ++ modinfo_section->append_data( attribute + '\0' ); ++ content.push_back( ++ std::pair<std::string, std::string>( field, value ) ); ++ } ++ ++ return current_position; ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ void process_section() ++ { ++ const char* pdata = modinfo_section->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i = 0; ++ while ( i < modinfo_section->get_size() ) { ++ while ( i < modinfo_section->get_size() && !pdata[i] ) ++ i++; ++ if ( i < modinfo_section->get_size() ) { ++ std::string info = pdata + i; ++ size_t loc = info.find( '=' ); ++ std::pair<std::string, std::string> attribute( ++ info.substr( 0, loc ), info.substr( loc + 1 ) ); ++ ++ content.push_back( attribute ); ++ ++ i += info.length(); ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ private: ++ S* modinfo_section; ++ std::vector<std::pair<std::string, std::string>> content; ++}; ++ ++using modinfo_section_accessor = modinfo_section_accessor_template<section>; ++using const_modinfo_section_accessor = ++ modinfo_section_accessor_template<const section>; ++ ++} // namespace ELFIO ++ ++#endif // ELFIO_MODINFO_HPP ++ ++/*** End of inlined file: elfio_modinfo.hpp ***/ ++ ++#ifdef _MSC_VER ++#pragma warning( pop ) ++#endif ++ ++#endif // ELFIO_HPP ++ ++/*** End of inlined file: elfio.hpp ***/ ++ ++ ++namespace ELFIO { ++ ++static struct class_table_t ++{ ++ const char key; ++ const char* str; ++} class_table[] = { ++ { ELFCLASS32, "ELF32" }, ++ { ELFCLASS64, "ELF64" }, ++}; ++ ++static struct endian_table_t ++{ ++ const char key; ++ const char* str; ++} endian_table[] = { ++ { ELFDATANONE, "None" }, ++ { ELFDATA2LSB, "Little endian" }, ++ { ELFDATA2MSB, "Big endian" }, ++}; ++ ++static struct version_table_t ++{ ++ const Elf64_Word key; ++ const char* str; ++} version_table[] = { ++ { EV_NONE, "None" }, ++ { EV_CURRENT, "Current" }, ++}; ++ ++static struct type_table_t ++{ ++ const Elf32_Half key; ++ const char* str; ++} type_table[] = { ++ { ET_NONE, "No file type" }, { ET_REL, "Relocatable file" }, ++ { ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" }, ++ { ET_CORE, "Core file" }, ++}; ++ ++static struct machine_table_t ++{ ++ const Elf64_Half key; ++ const char* str; ++} machine_table[] = { ++ { EM_NONE, "No machine" }, ++ { EM_M32, "AT&T WE 32100" }, ++ { EM_SPARC, "SUN SPARC" }, ++ { EM_386, "Intel 80386" }, ++ { EM_68K, "Motorola m68k family" }, ++ { EM_88K, "Motorola m88k family" }, ++ { EM_486, "Intel 80486// Reserved for future use" }, ++ { EM_860, "Intel 80860" }, ++ { EM_MIPS, "MIPS R3000 (officially, big-endian only)" }, ++ { EM_S370, "IBM System/370" }, ++ { EM_MIPS_RS3_LE, ++ "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, ++ { EM_res011, "Reserved" }, ++ { EM_res012, "Reserved" }, ++ { EM_res013, "Reserved" }, ++ { EM_res014, "Reserved" }, ++ { EM_PARISC, "HPPA" }, ++ { EM_res016, "Reserved" }, ++ { EM_VPP550, "Fujitsu VPP500" }, ++ { EM_SPARC32PLUS, "Sun's v8plus" }, ++ { EM_960, "Intel 80960" }, ++ { EM_PPC, "PowerPC" }, ++ { EM_PPC64, "64-bit PowerPC" }, ++ { EM_S390, "IBM S/390" }, ++ { EM_SPU, "Sony/Toshiba/IBM SPU" }, ++ { EM_res024, "Reserved" }, ++ { EM_res025, "Reserved" }, ++ { EM_res026, "Reserved" }, ++ { EM_res027, "Reserved" }, ++ { EM_res028, "Reserved" }, ++ { EM_res029, "Reserved" }, ++ { EM_res030, "Reserved" }, ++ { EM_res031, "Reserved" }, ++ { EM_res032, "Reserved" }, ++ { EM_res033, "Reserved" }, ++ { EM_res034, "Reserved" }, ++ { EM_res035, "Reserved" }, ++ { EM_V800, "NEC V800 series" }, ++ { EM_FR20, "Fujitsu FR20" }, ++ { EM_RH32, "TRW RH32" }, ++ { EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" }, ++ { EM_RCE, "Old name for MCore" }, ++ { EM_ARM, "ARM" }, ++ { EM_OLD_ALPHA, "Digital Alpha" }, ++ { EM_SH, "Renesas (formerly Hitachi) / SuperH SH" }, ++ { EM_SPARCV9, "SPARC v9 64-bit" }, ++ { EM_TRICORE, "Siemens Tricore embedded processor" }, ++ { EM_ARC, "ARC Cores" }, ++ { EM_H8_300, "Renesas (formerly Hitachi) H8/300" }, ++ { EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" }, ++ { EM_H8S, "Renesas (formerly Hitachi) H8S" }, ++ { EM_H8_500, "Renesas (formerly Hitachi) H8/500" }, ++ { EM_IA_64, "Intel IA-64 Processor" }, ++ { EM_MIPS_X, "Stanford MIPS-X" }, ++ { EM_COLDFIRE, "Motorola Coldfire" }, ++ { EM_68HC12, "Motorola M68HC12" }, ++ { EM_MMA, "Fujitsu Multimedia Accelerator" }, ++ { EM_PCP, "Siemens PCP" }, ++ { EM_NCPU, "Sony nCPU embedded RISC processor" }, ++ { EM_NDR1, "Denso NDR1 microprocesspr" }, ++ { EM_STARCORE, "Motorola Star*Core processor" }, ++ { EM_ME16, "Toyota ME16 processor" }, ++ { EM_ST100, "STMicroelectronics ST100 processor" }, ++ { EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" }, ++ { EM_X86_64, "Advanced Micro Devices X86-64 processor" }, ++ { EM_PDSP, "Sony DSP Processor" }, ++ { EM_PDP10, "Digital Equipment Corp. PDP-10" }, ++ { EM_PDP11, "Digital Equipment Corp. PDP-11" }, ++ { EM_FX66, "Siemens FX66 microcontroller" }, ++ { EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" }, ++ { EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" }, ++ { EM_68HC16, "Motorola MC68HC16 Microcontroller" }, ++ { EM_68HC11, "Motorola MC68HC11 Microcontroller" }, ++ { EM_68HC08, "Motorola MC68HC08 Microcontroller" }, ++ { EM_68HC05, "Motorola MC68HC05 Microcontroller" }, ++ { EM_SVX, "Silicon Graphics SVx" }, ++ { EM_ST19, "STMicroelectronics ST19 8-bit cpu" }, ++ { EM_VAX, "Digital VAX" }, ++ { EM_CRIS, "Axis Communications 32-bit embedded processor" }, ++ { EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" }, ++ { EM_FIREPATH, "Element 14 64-bit DSP processor" }, ++ { EM_ZSP, "LSI Logic's 16-bit DSP processor" }, ++ { EM_MMIX, "Donald Knuth's educational 64-bit processor" }, ++ { EM_HUANY, "Harvard's machine-independent format" }, ++ { EM_PRISM, "SiTera Prism" }, ++ { EM_AVR, "Atmel AVR 8-bit microcontroller" }, ++ { EM_FR30, "Fujitsu FR30" }, ++ { EM_D10V, "Mitsubishi D10V" }, ++ { EM_D30V, "Mitsubishi D30V" }, ++ { EM_V850, "NEC v850" }, ++ { EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" }, ++ { EM_MN10300, "Matsushita MN10300" }, ++ { EM_MN10200, "Matsushita MN10200" }, ++ { EM_PJ, "picoJava" }, ++ { EM_OPENRISC, "OpenRISC 32-bit embedded processor" }, ++ { EM_ARC_A5, "ARC Cores Tangent-A5" }, ++ { EM_XTENSA, "Tensilica Xtensa Architecture" }, ++ { EM_VIDEOCORE, "Alphamosaic VideoCore processor" }, ++ { EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" }, ++ { EM_NS32K, "National Semiconductor 32000 series" }, ++ { EM_TPC, "Tenor Network TPC processor" }, ++ { EM_SNP1K, "Trebia SNP 1000 processor" }, ++ { EM_ST200, "STMicroelectronics ST200 microcontroller" }, ++ { EM_IP2K, "Ubicom IP2022 micro controller" }, ++ { EM_MAX, "MAX Processor" }, ++ { EM_CR, "National Semiconductor CompactRISC" }, ++ { EM_F2MC16, "Fujitsu F2MC16" }, ++ { EM_MSP430, "TI msp430 micro controller" }, ++ { EM_BLACKFIN, "ADI Blackfin" }, ++ { EM_SE_C33, "S1C33 Family of Seiko Epson processors" }, ++ { EM_SEP, "Sharp embedded microprocessor" }, ++ { EM_ARCA, "Arca RISC Microprocessor" }, ++ { EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of " ++ "Peking University" }, ++ { EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" }, ++ { EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" }, ++ { EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" }, ++ { EM_CRX, "National Semiconductor CRX" }, ++ { EM_XGATE, "Motorola XGATE embedded processor" }, ++ { EM_C166, "Infineon C16x/XC16x processor" }, ++ { EM_M16C, "Renesas M16C series microprocessors" }, ++ { EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" }, ++ { EM_CE, "Freescale Communication Engine RISC core" }, ++ { EM_M32C, "Renesas M32C series microprocessors" }, ++ { EM_res121, "Reserved" }, ++ { EM_res122, "Reserved" }, ++ { EM_res123, "Reserved" }, ++ { EM_res124, "Reserved" }, ++ { EM_res125, "Reserved" }, ++ { EM_res126, "Reserved" }, ++ { EM_res127, "Reserved" }, ++ { EM_res128, "Reserved" }, ++ { EM_res129, "Reserved" }, ++ { EM_res130, "Reserved" }, ++ { EM_TSK3000, "Altium TSK3000 core" }, ++ { EM_RS08, "Freescale RS08 embedded processor" }, ++ { EM_res133, "Reserved" }, ++ { EM_ECOG2, "Cyan Technology eCOG2 microprocessor" }, ++ { EM_SCORE, "Sunplus Score" }, ++ { EM_SCORE7, "Sunplus S+core7 RISC processor" }, ++ { EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" }, ++ { EM_VIDEOCORE3, "Broadcom VideoCore III processor" }, ++ { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, ++ { EM_SE_C17, "Seiko Epson C17 family" }, ++ { EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" }, ++ { EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" }, ++ { EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" }, ++ { EM_res143, "Reserved" }, ++ { EM_res144, "Reserved" }, ++ { EM_res145, "Reserved" }, ++ { EM_res146, "Reserved" }, ++ { EM_res147, "Reserved" }, ++ { EM_res148, "Reserved" }, ++ { EM_res149, "Reserved" }, ++ { EM_res150, "Reserved" }, ++ { EM_res151, "Reserved" }, ++ { EM_res152, "Reserved" }, ++ { EM_res153, "Reserved" }, ++ { EM_res154, "Reserved" }, ++ { EM_res155, "Reserved" }, ++ { EM_res156, "Reserved" }, ++ { EM_res157, "Reserved" }, ++ { EM_res158, "Reserved" }, ++ { EM_res159, "Reserved" }, ++ { EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" }, ++ { EM_CYPRESS_M8C, "Cypress M8C microprocessor" }, ++ { EM_R32C, "Renesas R32C series microprocessors" }, ++ { EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" }, ++ { EM_QDSP6, "QUALCOMM DSP6 Processor" }, ++ { EM_8051, "Intel 8051 and variants" }, ++ { EM_STXP7X, "STMicroelectronics STxP7x family" }, ++ { EM_NDS32, ++ "Andes Technology compact code size embedded RISC processor family" }, ++ { EM_ECOG1, "Cyan Technology eCOG1X family" }, ++ { EM_ECOG1X, "Cyan Technology eCOG1X family" }, ++ { EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, ++ { EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" }, ++ { EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" }, ++ { EM_CRAYNV2, "Cray Inc. NV2 vector architecture" }, ++ { EM_RX, "Renesas RX family" }, ++ { EM_METAG, "Imagination Technologies META processor architecture" }, ++ { EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" }, ++ { EM_ECOG16, "Cyan Technology eCOG16 family" }, ++ { EM_CR16, "National Semiconductor CompactRISC 16-bit processor" }, ++ { EM_ETPU, "Freescale Extended Time Processing Unit" }, ++ { EM_SLE9X, "Infineon Technologies SLE9X core" }, ++ { EM_L1OM, "Intel L1OM" }, ++ { EM_INTEL181, "Reserved by Intel" }, ++ { EM_INTEL182, "Reserved by Intel" }, ++ { EM_res183, "Reserved by ARM" }, ++ { EM_res184, "Reserved by ARM" }, ++ { EM_AVR32, "Atmel Corporation 32-bit microprocessor family" }, ++ { EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" }, ++ { EM_TILE64, "Tilera TILE64 multicore architecture family" }, ++ { EM_TILEPRO, "Tilera TILEPro multicore architecture family" }, ++ { EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" }, ++ { EM_CUDA, "NVIDIA CUDA architecture " }, ++}; ++ ++static struct section_type_table_t ++{ ++ const Elf64_Half key; ++ const char* str; ++} section_type_table[] = { ++ { SHT_NULL, "NULL" }, ++ { SHT_PROGBITS, "PROGBITS" }, ++ { SHT_SYMTAB, "SYMTAB" }, ++ { SHT_STRTAB, "STRTAB" }, ++ { SHT_RELA, "RELA" }, ++ { SHT_HASH, "HASH" }, ++ { SHT_DYNAMIC, "DYNAMIC" }, ++ { SHT_NOTE, "NOTE" }, ++ { SHT_NOBITS, "NOBITS" }, ++ { SHT_REL, "REL" }, ++ { SHT_SHLIB, "SHLIB" }, ++ { SHT_DYNSYM, "DYNSYM" }, ++ { SHT_INIT_ARRAY, "INIT_ARRAY" }, ++ { SHT_FINI_ARRAY, "FINI_ARRAY" }, ++ { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, ++ { SHT_GROUP, "GROUP" }, ++ { SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " }, ++}; ++ ++static struct segment_type_table_t ++{ ++ const Elf_Word key; ++ const char* str; ++} segment_type_table[] = { ++ { PT_NULL, "NULL" }, { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" }, ++ { PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" }, ++ { PT_PHDR, "PHDR" }, { PT_TLS, "TLS" }, ++}; ++ ++static struct segment_flag_table_t ++{ ++ const Elf_Word key; ++ const char* str; ++} segment_flag_table[] = { ++ { 0, "" }, { 1, "X" }, { 2, "W" }, { 3, "WX" }, ++ { 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" }, ++}; ++ ++static struct symbol_bind_t ++{ ++ const Elf_Word key; ++ const char* str; ++} symbol_bind_table[] = { ++ { STB_LOCAL, "LOCAL" }, { STB_GLOBAL, "GLOBAL" }, ++ { STB_WEAK, "WEAK" }, { STB_LOOS, "LOOS" }, ++ { STB_HIOS, "HIOS" }, { STB_MULTIDEF, "MULTIDEF" }, ++ { STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" }, ++}; ++ ++static struct symbol_type_t ++{ ++ const Elf_Word key; ++ const char* str; ++} symbol_type_table[] = { ++ { STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" }, ++ { STT_FUNC, "FUNC" }, { STT_SECTION, "SECTION" }, ++ { STT_FILE, "FILE" }, { STT_COMMON, "COMMON" }, ++ { STT_TLS, "TLS" }, { STT_LOOS, "LOOS" }, ++ { STT_HIOS, "HIOS" }, { STT_LOPROC, "LOPROC" }, ++ { STT_HIPROC, "HIPROC" }, ++}; ++ ++static struct dynamic_tag_t ++{ ++ const Elf_Word key; ++ const char* str; ++} dynamic_tag_table[] = { ++ { DT_NULL, "NULL" }, ++ { DT_NEEDED, "NEEDED" }, ++ { DT_PLTRELSZ, "PLTRELSZ" }, ++ { DT_PLTGOT, "PLTGOT" }, ++ { DT_HASH, "HASH" }, ++ { DT_STRTAB, "STRTAB" }, ++ { DT_SYMTAB, "SYMTAB" }, ++ { DT_RELA, "RELA" }, ++ { DT_RELASZ, "RELASZ" }, ++ { DT_RELAENT, "RELAENT" }, ++ { DT_STRSZ, "STRSZ" }, ++ { DT_SYMENT, "SYMENT" }, ++ { DT_INIT, "INIT" }, ++ { DT_FINI, "FINI" }, ++ { DT_SONAME, "SONAME" }, ++ { DT_RPATH, "RPATH" }, ++ { DT_SYMBOLIC, "SYMBOLIC" }, ++ { DT_REL, "REL" }, ++ { DT_RELSZ, "RELSZ" }, ++ { DT_RELENT, "RELENT" }, ++ { DT_PLTREL, "PLTREL" }, ++ { DT_DEBUG, "DEBUG" }, ++ { DT_TEXTREL, "TEXTREL" }, ++ { DT_JMPREL, "JMPREL" }, ++ { DT_BIND_NOW, "BIND_NOW" }, ++ { DT_INIT_ARRAY, "INIT_ARRAY" }, ++ { DT_FINI_ARRAY, "FINI_ARRAY" }, ++ { DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" }, ++ { DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" }, ++ { DT_RUNPATH, "RUNPATH" }, ++ { DT_FLAGS, "FLAGS" }, ++ { DT_ENCODING, "ENCODING" }, ++ { DT_PREINIT_ARRAY, "PREINIT_ARRAY" }, ++ { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, ++ { DT_MAXPOSTAGS, "MAXPOSTAGS" }, ++}; ++ ++static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; ++ ++//------------------------------------------------------------------------------ ++class dump ++{ ++#define DUMP_DEC_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right ++#define DUMP_HEX_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( '0' ) << std::hex << std::right ++#define DUMP_STR_FORMAT( width ) \ ++ std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left ++ ++ public: ++ //------------------------------------------------------------------------------ ++ static void header( std::ostream& out, const elfio& reader ) ++ { ++ if ( !reader.get_header_size() ) { ++ return; ++ } ++ out << "ELF Header" << std::endl ++ << std::endl ++ << " Class: " << str_class( reader.get_class() ) << std::endl ++ << " Encoding: " << str_endian( reader.get_encoding() ) ++ << std::endl ++ << " ELFVersion: " << str_version( reader.get_elf_version() ) ++ << std::endl ++ << " Type: " << str_type( reader.get_type() ) << std::endl ++ << " Machine: " << str_machine( reader.get_machine() ) ++ << std::endl ++ << " Version: " << str_version( reader.get_version() ) ++ << std::endl ++ << " Entry: " ++ << "0x" << std::hex << reader.get_entry() << std::endl ++ << " Flags: " ++ << "0x" << std::hex << reader.get_flags() << std::endl ++ << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_headers( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Section Headers:" << std::endl; ++ if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Type Addr Size ES Flg Lk Inf " ++ "Al Name" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Type Addr Size " ++ " ES Flg" ++ << std::endl ++ << " Lk Inf Al Name" << std::endl; ++ } ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ section_header( out, i, sec, reader.get_class() ); ++ } ++ ++ out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" ++ << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_header( std::ostream& out, ++ Elf_Half no, ++ const section* sec, ++ unsigned char elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " ++ << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " ++ << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " ++ << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) ++ << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " ++ << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " ++ << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " ++ << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " ++ << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " ++ << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) ++ << " " << std::endl ++ << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " ++ << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " ++ << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_headers( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.segments.size(); ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Segment headers:" << std::endl; ++ if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size " ++ "Flags Align" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Type VirtAddr PhysAddr " ++ "Flags" ++ << std::endl ++ << " FileSize Mem.Size " ++ "Align" ++ << std::endl; ++ } ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { ++ segment* seg = reader.segments[i]; ++ segment_header( out, i, seg, reader.get_class() ); ++ } ++ ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_header( std::ostream& out, ++ Elf_Half no, ++ const segment* seg, ++ unsigned int elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " ++ << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " ++ << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) ++ << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) ++ << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() ++ << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() ++ << " " << DUMP_STR_FORMAT( 16 ) ++ << str_segment_flag( seg->get_flags() ) << " " << std::endl ++ << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 ) ++ << seg->get_align() << " " << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void symbol_tables( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_SYMTAB == sec->get_type() || ++ SHT_DYNSYM == sec->get_type() ) { ++ symbol_section_accessor symbols( reader, sec ); ++ ++ Elf_Xword sym_no = symbols.get_symbols_num(); ++ if ( sym_no > 0 ) { ++ out << "Symbol table (" << sec->get_name() << ")" ++ << std::endl; ++ if ( reader.get_class() == ++ ELFCLASS32 ) { // Output for 32-bit ++ out << "[ Nr ] Value Size Type Bind " ++ "Sect Name" ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[ Nr ] Value Size Type " ++ " Bind Sect" ++ << std::endl ++ << " Name" << std::endl; ++ } ++ for ( Elf_Xword i = 0; i < sym_no; ++i ) { ++ std::string name; ++ Elf64_Addr value = 0; ++ Elf_Xword size = 0; ++ unsigned char bind = 0; ++ unsigned char type = 0; ++ Elf_Half section = 0; ++ unsigned char other = 0; ++ symbols.get_symbol( i, name, value, size, bind, type, ++ section, other ); ++ symbol_table( out, i, name, value, size, bind, type, ++ section, reader.get_class() ); ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void symbol_table( std::ostream& out, ++ Elf_Xword no, ++ std::string& name, ++ Elf64_Addr value, ++ Elf_Xword size, ++ unsigned char bind, ++ unsigned char type, ++ Elf_Half section, ++ unsigned int elf_class ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ if ( elf_class == ELFCLASS32 ) { // Output for 32-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 ) ++ << size << " " << DUMP_STR_FORMAT( 7 ) ++ << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) ++ << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) ++ << section << " " << DUMP_STR_FORMAT( 1 ) << name << " " ++ << std::endl; ++ } ++ else { // Output for 64-bit ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_HEX_FORMAT( 16 ) << value << " " ++ << DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 ) ++ << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) ++ << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) ++ << section << " " << std::endl ++ << " " << DUMP_STR_FORMAT( 1 ) << name << " " ++ << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void notes( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half no = reader.sections.size(); ++ for ( Elf_Half i = 0; i < no; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_NOTE == sec->get_type() ) { // Look at notes ++ note_section_accessor notes( reader, sec ); ++ Elf_Word no_notes = notes.get_notes_num(); ++ if ( no > 0 ) { ++ out << "Note section (" << sec->get_name() << ")" ++ << std::endl ++ << " No Type Name" << std::endl; ++ for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes ++ Elf_Word type; ++ std::string name; ++ void* desc; ++ Elf_Word descsz; ++ ++ if ( notes.get_note( j, type, name, desc, descsz ) ) { ++ // 'name' usually contains \0 at the end. Try to fix it ++ name = name.c_str(); ++ note( out, j, type, name ); ++ } ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void modinfo( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half no = reader.sections.size(); ++ for ( Elf_Half i = 0; i < no; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( ".modinfo" == sec->get_name() ) { // Look for the section ++ out << "Section .modinfo" << std::endl; ++ ++ const_modinfo_section_accessor modinfo( sec ); ++ for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) { ++ std::string field; ++ std::string value; ++ if ( modinfo.get_attribute( i, field, value ) ) { ++ out << " " << std::setw( 20 ) << field ++ << std::setw( 0 ) << " = " << value << std::endl; ++ } ++ } ++ ++ out << std::endl; ++ break; ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void ++ note( std::ostream& out, int no, Elf_Word type, const std::string& name ) ++ { ++ out << " [" << DUMP_DEC_FORMAT( 2 ) << no << "] " ++ << DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 ) ++ << name << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void dynamic_tags( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( SHT_DYNAMIC == sec->get_type() ) { ++ dynamic_section_accessor dynamic( reader, sec ); ++ ++ Elf_Xword dyn_no = dynamic.get_entries_num(); ++ if ( dyn_no > 0 ) { ++ out << "Dynamic section (" << sec->get_name() << ")" ++ << std::endl; ++ out << "[ Nr ] Tag Name/Value" << std::endl; ++ for ( Elf_Xword i = 0; i < dyn_no; ++i ) { ++ Elf_Xword tag = 0; ++ Elf_Xword value = 0; ++ std::string str; ++ dynamic.get_entry( i, tag, value, str ); ++ dynamic_tag( out, i, tag, value, str, ++ reader.get_class() ); ++ if ( DT_NULL == tag ) { ++ break; ++ } ++ } ++ ++ out << std::endl; ++ } ++ } ++ } ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void dynamic_tag( std::ostream& out, ++ Elf_Xword no, ++ Elf_Xword tag, ++ Elf_Xword value, ++ std::string str, ++ unsigned int /*elf_class*/ ) ++ { ++ out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " ++ << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; ++ if ( str.empty() ) { ++ out << DUMP_HEX_FORMAT( 16 ) << value << " "; ++ } ++ else { ++ out << DUMP_STR_FORMAT( 32 ) << str << " "; ++ } ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_data( std::ostream& out, const section* sec ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ out << sec->get_name() << std::endl; ++ const char* pdata = sec->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i; ++ for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++ ++i ) { ++ if ( i % 16 == 0 ) { ++ out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; ++ } ++ ++ out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); ++ ++ if ( i % 16 == 15 ) { ++ out << std::endl; ++ } ++ } ++ if ( i % 16 != 0 ) { ++ out << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void section_datas( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.sections.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Section Data:" << std::endl; ++ ++ for ( Elf_Half i = 1; i < n; ++i ) { // For all sections ++ section* sec = reader.sections[i]; ++ if ( sec->get_type() == SHT_NOBITS ) { ++ continue; ++ } ++ section_data( out, sec ); ++ } ++ ++ out << std::endl; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void ++ segment_data( std::ostream& out, Elf_Half no, const segment* seg ) ++ { ++ std::ios_base::fmtflags original_flags = out.flags(); ++ ++ out << "Segment # " << no << std::endl; ++ const char* pdata = seg->get_data(); ++ if ( pdata ) { ++ ELFIO::Elf_Xword i; ++ for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++ ++i ) { ++ if ( i % 16 == 0 ) { ++ out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; ++ } ++ ++ out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); ++ ++ if ( i % 16 == 15 ) { ++ out << std::endl; ++ } ++ } ++ if ( i % 16 != 0 ) { ++ out << std::endl; ++ } ++ ++ out.flags( original_flags ); ++ } ++ ++ return; ++ } ++ ++ //------------------------------------------------------------------------------ ++ static void segment_datas( std::ostream& out, const elfio& reader ) ++ { ++ Elf_Half n = reader.segments.size(); ++ ++ if ( n == 0 ) { ++ return; ++ } ++ ++ out << "Segment Data:" << std::endl; ++ ++ for ( Elf_Half i = 0; i < n; ++i ) { // For all sections ++ segment* seg = reader.segments[i]; ++ segment_data( out, i, seg ); ++ } ++ ++ out << std::endl; ++ } ++ ++ private: ++ //------------------------------------------------------------------------------ ++ template <typename T, typename K> ++ std::string static find_value_in_table( const T& table, const K& key ) ++ { ++ std::string res = "?"; ++ for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] ); ++ ++i ) { ++ if ( table[i].key == key ) { ++ res = table[i].str; ++ break; ++ } ++ } ++ ++ return res; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <typename T, typename K> ++ static std::string format_assoc( const T& table, const K& key ) ++ { ++ std::string str = find_value_in_table( table, key ); ++ if ( str == "?" ) { ++ std::ostringstream oss; ++ oss << str << " (0x" << std::hex << key << ")"; ++ str = oss.str(); ++ } ++ ++ return str; ++ } ++ ++ //------------------------------------------------------------------------------ ++ template <typename T> ++ static std::string format_assoc( const T& table, const char key ) ++ { ++ return format_assoc( table, (const int)key ); ++ } ++ ++ //------------------------------------------------------------------------------ ++ static std::string section_flags( Elf_Xword flags ) ++ { ++ std::string ret = ""; ++ if ( flags & SHF_WRITE ) { ++ ret += "W"; ++ } ++ if ( flags & SHF_ALLOC ) { ++ ret += "A"; ++ } ++ if ( flags & SHF_EXECINSTR ) { ++ ret += "X"; ++ } ++ ++ return ret; ++ } ++ ++//------------------------------------------------------------------------------ ++#define STR_FUNC_TABLE( name ) \ ++ template <typename T> static std::string str_##name( const T key ) \ ++ { \ ++ return format_assoc( name##_table, key ); \ ++ } ++ ++ STR_FUNC_TABLE( class ) ++ STR_FUNC_TABLE( endian ) ++ STR_FUNC_TABLE( version ) ++ STR_FUNC_TABLE( type ) ++ STR_FUNC_TABLE( machine ) ++ STR_FUNC_TABLE( section_type ) ++ STR_FUNC_TABLE( segment_type ) ++ STR_FUNC_TABLE( segment_flag ) ++ STR_FUNC_TABLE( symbol_bind ) ++ STR_FUNC_TABLE( symbol_type ) ++ STR_FUNC_TABLE( dynamic_tag ) ++ ++#undef STR_FUNC_TABLE ++#undef DUMP_DEC_FORMAT ++#undef DUMP_HEX_FORMAT ++#undef DUMP_STR_FORMAT ++}; // class dump ++ ++}; // namespace ELFIO ++ ++#endif // ELFIO_DUMP_HPP ++ ++/*** End of inlined file: elfio_dump.hpp ***/ ++ +diff --git a/tests/kt-test-utils/cpp-stub/stub.h b/tests/kt-test-utils/cpp-stub/stub.h +new file mode 100644 +index 0000000..5184595 +--- /dev/null ++++ b/tests/kt-test-utils/cpp-stub/stub.h +@@ -0,0 +1,378 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#ifndef __STUB_H__ ++#define __STUB_H__ ++ ++#ifdef _WIN32 ++//windows ++#include <windows.h> ++#include <processthreadsapi.h> ++#else ++//linux ++#include <unistd.h> ++#include <bits/stdint-uintn.h> ++#include <sys/mman.h> ++#endif ++//c ++#include <cstddef> ++#include <cstring> ++//c++ ++#include <map> ++ ++ ++#define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME) ++ ++/********************************************************** ++ replace function ++**********************************************************/ ++#ifdef _WIN32 ++#define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size) ++#else ++#define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) ++#endif ++ ++#if defined(__aarch64__) || defined(_M_ARM64) ++ #define CODESIZE 16U ++ #define CODESIZE_MIN 16U ++ #define CODESIZE_MAX CODESIZE ++ // ldr x9, +8 ++ // br x9 ++ // addr ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t*)fn)[0] = 0x58000040 | 9;\ ++ ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\ ++ *(long long *)(fn + 8) = (long long )fn_stub;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__arm__) || defined(_M_ARM) ++ #define CODESIZE 8U ++ #define CODESIZE_MIN 8U ++ #define CODESIZE_MAX CODESIZE ++ // ldr pc, [pc, #-4] ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t*)fn)[0] = 0xe51ff004;\ ++ ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__mips64) ++ #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) ++ #define CODESIZE 80U ++ #define CODESIZE_MIN 80U ++ #define CODESIZE_MAX CODESIZE ++ //mips没有PC指针,所以需要手动入栈出栈 ++ //120000ce0: 67bdffe0 daddiu sp, sp, -32 //入栈 ++ //120000ce4: ffbf0018 sd ra, 24(sp) ++ //120000ce8: ffbe0010 sd s8, 16(sp) ++ //120000cec: ffbc0008 sd gp, 8(sp) ++ //120000cf0: 03a0f025 move s8, sp ++ ++ //120000d2c: 03c0e825 move sp, s8 //出栈 ++ //120000d30: dfbf0018 ld ra, 24(sp) ++ //120000d34: dfbe0010 ld s8, 16(sp) ++ //120000d38: dfbc0008 ld gp, 8(sp) ++ //120000d3c: 67bd0020 daddiu sp, sp, 32 ++ //120000d40: 03e00008 jr ra ++ ++ #define REPLACE_FAR(t, fn, fn_stub)\ ++ ((uint32_t *)fn)[0] = 0x67bdffe0;\ ++ ((uint32_t *)fn)[1] = 0xffbf0018;\ ++ ((uint32_t *)fn)[2] = 0xffbe0010;\ ++ ((uint32_t *)fn)[3] = 0xffbc0008;\ ++ ((uint32_t *)fn)[4] = 0x03a0f025;\ ++ *(uint16_t *)(fn + 20) = (long long)fn_stub >> 32;\ ++ *(fn + 22) = 0x19;\ ++ *(fn + 23) = 0x24;\ ++ ((uint32_t *)fn)[6] = 0x0019cc38;\ ++ *(uint16_t *)(fn + 28) = (long long)fn_stub >> 16;\ ++ *(fn + 30) = 0x39;\ ++ *(fn + 31) = 0x37;\ ++ ((uint32_t *)fn)[8] = 0x0019cc38;\ ++ *(uint16_t *)(fn + 36) = (long long)fn_stub;\ ++ *(fn + 38) = 0x39;\ ++ *(fn + 39) = 0x37;\ ++ ((uint32_t *)fn)[10] = 0x0320f809;\ ++ ((uint32_t *)fn)[11] = 0x00000000;\ ++ ((uint32_t *)fn)[12] = 0x00000000;\ ++ ((uint32_t *)fn)[13] = 0x03c0e825;\ ++ ((uint32_t *)fn)[14] = 0xdfbf0018;\ ++ ((uint32_t *)fn)[15] = 0xdfbe0010;\ ++ ((uint32_t *)fn)[16] = 0xdfbc0008;\ ++ ((uint32_t *)fn)[17] = 0x67bd0020;\ ++ ((uint32_t *)fn)[18] = 0x03e00008;\ ++ ((uint32_t *)fn)[19] = 0x00000000;\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++ #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) ++#elif defined(__thumb__) || defined(_M_THUMB) ++ #error "Thumb is not supported" ++#else //__i386__ _x86_64__ ++ #define CODESIZE 13U ++ #define CODESIZE_MIN 5U ++ #define CODESIZE_MAX CODESIZE ++ //13 byte(jmp m16:64) ++ //movabs $0x102030405060708,%r11 ++ //jmpq *%r11 ++ static void REPLACE_FAR(void *t, char *fn, char *fn_stub) ++ { ++ *fn = 0x49; ++ *(fn + 1) = 0xbb; ++ *(long long *)(fn + 2) = (long long)fn_stub; ++ *(fn + 10) = 0x41; ++ *(fn + 11) = 0xff; ++ *(fn + 12) = 0xe3; ++ CACHEFLUSH((char *)fn, CODESIZE); ++ } ++ //5 byte(jmp rel32) ++ #define REPLACE_NEAR(t, fn, fn_stub)\ ++ *fn = 0xE9;\ ++ *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\ ++ CACHEFLUSH((char *)fn, CODESIZE); ++#endif ++ ++struct func_stub ++{ ++ char *fn; ++ unsigned char code_buf[CODESIZE]; ++ bool far_jmp; ++}; ++ ++class Stub ++{ ++public: ++ Stub() ++ { ++#ifdef _WIN32 ++ SYSTEM_INFO sys_info; ++ GetSystemInfo(&sys_info); ++ m_pagesize = sys_info.dwPageSize; ++#else ++ m_pagesize = sysconf(_SC_PAGE_SIZE); ++#endif ++ ++ if (m_pagesize < 0) ++ { ++ m_pagesize = 4096; ++ } ++ } ++ ~Stub() ++ { ++ clear(); ++ } ++ ++ virtual void clear() ++ { ++ std::map<char*,func_stub*>::iterator iter; ++ struct func_stub *pstub; ++ for(iter=m_result.begin(); iter != m_result.end(); iter++) ++ { ++ pstub = iter->second; ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ ++ if(pstub->far_jmp) ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); ++ } ++ else ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); ++ } ++ ++#ifdef _WIN32 ++ VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect); ++#else ++ CACHEFLUSH(pstub->fn,CODESIZE); ++ mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC); ++#endif ++ } ++ ++ iter->second = NULL; ++ delete pstub; ++ } ++ ++ m_result.clear(); ++ return; ++ } ++ template<typename T,typename S> ++ bool set(T addr, S addr_stub) ++ { ++ char * fn; ++ char * fn_stub; ++ fn = addrof(addr); ++ fn_stub = addrof(addr_stub); ++ struct func_stub *pstub; ++ std::map<char*,func_stub*>::iterator iter = m_result.find(fn); ++ ++ if (iter == m_result.end()) ++ { ++ pstub = new func_stub; ++ //start ++ pstub->fn = fn; ++ ++ if(distanceof(fn, fn_stub)) ++ { ++ pstub->far_jmp = true; ++ std::memcpy(pstub->code_buf, fn, CODESIZE_MAX); ++ } ++ else ++ { ++ pstub->far_jmp = false; ++ std::memcpy(pstub->code_buf, fn, CODESIZE_MIN); ++ } ++ } ++ else { ++ pstub = iter->second; ++ pstub->far_jmp = distanceof(fn, fn_stub); ++ } ++ ++ ++ ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), static_cast<size_t>(m_pagesize * 2), PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ throw("stub set memory protect to w+r+x faild"); ++ return false; ++ } ++ ++ if(pstub->far_jmp) ++ { ++ REPLACE_FAR(this, fn, fn_stub); ++ } ++ else ++ { ++ REPLACE_NEAR(this, fn, fn_stub); ++ } ++ ++ ++#ifdef _WIN32 ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) ++#endif ++ { ++ throw("stub set memory protect to r+x failed"); ++ return false; ++ } ++ m_result.insert(std::pair<char*,func_stub*>(fn,pstub)); ++ return true; ++ } ++ ++ template<typename T> ++ bool reset(T addr) ++ { ++ char * fn; ++ fn = addrof(addr); ++ ++ std::map<char*,func_stub*>::iterator iter = m_result.find(fn); ++ ++ if (iter == m_result.end()) ++ { ++ return true; ++ } ++ struct func_stub *pstub; ++ pstub = iter->second; ++ ++#ifdef _WIN32 ++ DWORD lpflOldProtect; ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) ++#else ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) ++#endif ++ { ++ throw("stub reset memory protect to w+r+x faild"); ++ return false; ++ } ++ ++ if(pstub->far_jmp) ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); ++ } ++ else ++ { ++ std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); ++ } ++ ++#ifdef _WIN32 ++ if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) ++#else ++ CACHEFLUSH(pstub->fn,CODESIZE); ++ if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) ++#endif ++ { ++ throw("stub reset memory protect to r+x failed"); ++ return false; ++ } ++ ++ m_result.erase(iter); ++ delete pstub; ++ ++ return true; ++ } ++protected: ++ char *pageof(char* addr) ++ { ++#ifdef _WIN32 ++ return (char *)((unsigned long long)addr & ~(m_pagesize - 1)); ++#else ++ return (char *)((unsigned long)addr & ~(m_pagesize - 1)); ++#endif ++ } ++ ++ template<typename T> ++ char* addrof(T addr) ++ { ++ union ++ { ++ T _s; ++ char* _d; ++ }ut; ++ ut._s = addr; ++ return ut._d; ++ } ++ ++ bool distanceof(char* addr, char* addr_stub) ++ { ++ std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub; ++ if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0)) ++ { ++ return true; ++ } ++ return false; ++ } ++ ++protected: ++#ifdef _WIN32 ++ //LLP64 ++ long long m_pagesize; ++#else ++ //LP64 ++ long m_pagesize; ++#endif ++ std::map<char*, func_stub*> m_result; ++}; ++ ++#endif +diff --git a/tests/main.cpp b/tests/main.cpp +new file mode 100644 +index 0000000..7196885 +--- /dev/null ++++ b/tests/main.cpp +@@ -0,0 +1,9 @@ ++#include <gtest/gtest.h> ++ ++int main(int argc, char **argv) ++{ ++ testing::InitGoogleTest(&argc, argv); ++ ++ return RUN_ALL_TESTS(); ++} ++ +diff --git a/tests/tests.pro b/tests/tests.pro +new file mode 100644 +index 0000000..e9d46a1 +--- /dev/null ++++ b/tests/tests.pro +@@ -0,0 +1,101 @@ ++QT += dbus concurrent KWindowSystem ++#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets ++ ++include(../src/procnet-monitor/procnet-monitor.pri) ++ ++TEMPLATE = app ++ ++TARGET = unit_test_systemmonitor ++target.source += $$TARGET ++target.path = ./ ++ ++#代码覆盖率工具gcov ++QMAKE_LFLAGS +=-fprofile-arcs -ftest-coverage ++QMAKE_CXXFLAGS += --coverage -fno-inline -fno-access-control ++ ++LIBS += -lgtest_main -lpthread ++LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lgtest -lgcov -lpcap ++ ++CONFIG += link_pkgconfig \ ++ c++11 ++ ++PKGCONFIG += libgtop-2.0 \ ++ libsystemd \ ++ kysdk-utils \ ++ kysdk-waylandhelper \ ++ kysdk-sysinfo \ ++ kysdk-proc \ ++ kysdk-hardware \ ++ kysdk-net \ ++ kysdk-realtime \ ++ ++#OBJECTS_DIR = ./obj ++#MOC_DIR = ./moc ++ ++# 打桩工具 ++# Define paths ++TEST_UTILS_PATH = $$PWD/kt-test-utils ++ ++INCLUDEPATH += $$TEST_UTILS_PATH/cpp-stub \ ++ $$TEST_UTILS_PATH/cpp-stub-ext \ ++ ++# Header files (if needed) ++HEADERS += $$files($$TEST_UTILS_PATH/cpp-stub/*.h) \ ++ $$files($$TEST_UTILS_PATH/cpp-stub/*.hpp) \ ++ $$files($$TEST_UTILS_PATH/cpp-stub-ext/*.h) ++ ++# Gather source files ++SOURCES += $$files($$TEST_UTILS_PATH/cpp-stub/*.cpp) \ ++ $$files($$TEST_UTILS_PATH/cpp-stub-ext/*.cpp) \ ++ ++# source files ++SOURCES += ../src/filesystem/filesystemworker.cpp \ ++ ../src/filesystem/filesystemdata.cpp \ ++ ../src/filesystem/datacdrom.cpp \ ++ ../src/util.cpp \ ++ ../src/service/servicedataworker.cpp \ ++ ../src/service/servicemanager.cpp \ ++ ../src/service/serviceinfo.cpp \ ++ ../src/service/kerror.cpp \ ++ ../src/service/systemd1managerinterface.cpp \ ++ ../src/service/systemd1serviceinterface.cpp \ ++ ../src/service/servicefileinfo.cpp \ ++ ../src/service/dbuspropertiesinterface.cpp \ ++ ../src/sysresource/commoninfo.cpp \ ++ ../src/process/process_monitor.cpp \ ++ ../src/process/process_list.cpp \ ++ ../src/process/process_network.cpp \ ++ ../src/process/processwndinfo.cpp \ ++ ../src/desktopfileinfo.cpp \ ++ ++ ++HEADERS += ../src/filesystem/filesystemworker.h \ ++ ../src/filesystem/filesystemdata.h \ ++ ../src/filesystem/datacdrom.h \ ++ ../src/util.h \ ++ ../src/service/servicedataworker.h \ ++ ../src/service/servicemanager.h \ ++ ../src/service/serviceinfo.h \ ++ ../src/service/kerror.h \ ++ ../src/service/systemd1managerinterface.h \ ++ ../src/service/systemd1serviceinterface.h \ ++ ../src/service/servicecommon.h \ ++ ../src/service/servicefileinfo.h \ ++ ../src/service/dbuspropertiesinterface.h \ ++ ../src/sysresource/commoninfo.h \ ++ ../src/process/process_monitor.h \ ++ ../src/process/process_list.h \ ++ ../src/process/process_data.h \ ++ ../src/process/process_network.h \ ++ ../src/process/processwndinfo.h \ ++ ../src/desktopfileinfo.h \ ++ ++ ++# unit test files ++SOURCES += main.cpp \ ++ unit_test_filesystem.cpp \ ++ unit_test_service.cpp \ ++ unit_test_commoninfo.cpp \ ++ unit_test_utils.cpp \ ++ unit_test_process.cpp \ ++ +diff --git a/tests/unit_test_commoninfo.cpp b/tests/unit_test_commoninfo.cpp +new file mode 100644 +index 0000000..e645fc0 +--- /dev/null ++++ b/tests/unit_test_commoninfo.cpp +@@ -0,0 +1,113 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../src/sysresource/commoninfo.h" ++ ++class CommoninfoTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ } ++ ++ static void TearDownTestSuite() ++ { ++ } ++}; ++ ++TEST_F(CommoninfoTest, cpuInfoTest) ++{ ++ cpuInfo::getUtilization(); // 获取总利用率 ++ cpuInfo::getCurrentFrequency(); // 获取当前频率 ++ cpuInfo::getFrequency(); // 获取频率 ++ cpuInfo::getUpTime(); // 获取运行时间 ++ cpuInfo::getSockets(); // 获取插槽 ++ cpuInfo::getLogicalProcessors(); // 获取逻辑处理器 ++ cpuInfo::getVirtualization(); // 获取虚拟化 ++ cpuInfo::getL1iCache(); // 获取 L1 缓存(指令) ++ cpuInfo::getL1dCache(); // 获取 L1 缓存(数据) ++ cpuInfo::getL2Cache(); // 获取 L2 缓存 ++ cpuInfo::getL3Cache(); // 获取 L3 缓存 ++ cpuInfo::getLoadAverage(); // 获取负载均衡 ++ cpuInfo::getFileDescriptors(); // 获取文件描述符数 ++ cpuInfo::getProcesses(); // 获取进程数 ++ cpuInfo::getThreads(); // 获取线程数 ++ cpuInfo::getHostName(); // 获取计算机名 ++ cpuInfo::getOSType(); // 获取类型 ++ cpuInfo::getVersion(); // 获取版本名称 ++} ++ ++TEST_F(CommoninfoTest, memInfoTest) ++{ ++ memInfo::getUsed(); // 获取已使用 ++ memInfo::getAvailable(); // 获取可使用 ++ memInfo::getShared(); // 获取共享内存 ++ memInfo::getCached(); // 获取高速缓存 ++ memInfo::getBuffers(); // 获取数据缓存 ++ memInfo::getCachedSwap(); // 获取交换缓存区 ++ memInfo::getActive(); // 获取活跃的缓冲文件 ++ memInfo::getInActive(); // 获取不活跃的缓冲文件 ++ memInfo::getDirty(); // 获取脏页 ++ memInfo::getMapped(); // 获取映射大小 ++ memInfo::getTotalSwap(); // 获取交换空间大小 ++ memInfo::getFreeSwap(); // 获取可用交换空间 ++ memInfo::getSlab(); // 获取内核数据结构缓存 ++} ++TEST_F(CommoninfoTest, netInfoTest) ++{ ++ QStringList cardNameList = netInfo::getAllCards(); // 获取所有网卡列表 ++ ++ QStringList upCardNameList = netInfo::getUpCards(); // 获取up状态网卡列表 ++ ++ QString cardName = "enp5s0"; ++ ++ if (!cardNameList.isEmpty()) { ++ cardName = cardNameList.at(0); ++ } ++ ++ std::string str = cardName.toStdString(); ++ const char *NCName = str.c_str(); ++ ++ netInfo::getIPv4Address(NCName); // 获取 IPv4 地址 ++ netInfo::getIPv6Address(NCName); // 获取 IPv6 地址 ++ netInfo::getConnectType(NCName); // 获取连接类型 ++ netInfo::getNetName(NCName); // 获取网络名称 ++ netInfo::getSignalQuality(NCName); // 获取信号质量 ++ netInfo::getSignalStrength(NCName); // 获取信号强度 ++ netInfo::getNoiseLevel(NCName); // 获取底噪 ++ netInfo::getMacAddress(NCName); // 获取 MAC 地址 ++ netInfo::getSpeed(NCName); // 获取速率 ++ netInfo::getRecvPackets(NCName); // 获取接收包数量 ++ netInfo::getRecvTotal(NCName); // 获取总计接收 ++ netInfo::getRecvErrors(NCName); // 获取接收错误包 ++ netInfo::getRecvDropped(NCName); // 获取接收丢弃包 ++ netInfo::getRecvFIFO(NCName); // 获取接收 FIFO ++ netInfo::getFrameErrors(NCName); // 获取分组帧错误 ++ netInfo::getSendPackets(NCName); // 获取发送包数量 ++ netInfo::getSendTotal(NCName); // 获取总计发送 ++ netInfo::getSendErrors(NCName); // 获取发送错误包 ++ netInfo::getSendDropped(NCName); // 获取发送丢弃宝 ++ netInfo::getSendFIFO(NCName); // 获取发送FIFO ++ netInfo::getCarrierLoss(NCName); // 获取载波损耗 ++ ++ netInfo::getIPv4AddressList(NCName); // 获取ipv4地址列表 ++ netInfo::getIPv6AddressList(NCName); // 获取ipv6地址列表 ++} +diff --git a/tests/unit_test_filesystem.cpp b/tests/unit_test_filesystem.cpp +new file mode 100644 +index 0000000..af5fad1 +--- /dev/null ++++ b/tests/unit_test_filesystem.cpp +@@ -0,0 +1,118 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../src/filesystem/filesystemworker.h" ++#include "../src/filesystem/datacdrom.h" ++ ++#include "kt-test-utils/cpp-stub-ext/stubext.h" ++using namespace stub_ext; ++ ++class FilesystemTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pFilesystemWorker = new FileSystemWorker(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pFilesystemWorker; ++ m_pFilesystemWorker = nullptr; ++ } ++ ++ static FileSystemWorker *m_pFilesystemWorker; ++}; ++ ++FileSystemWorker *FilesystemTest::m_pFilesystemWorker = nullptr; ++ ++TEST_F(FilesystemTest, FileSystemWorker) ++{ ++ m_pFilesystemWorker->onFileSystemListChanged(); ++ ++ QList<QString> filesytemList = m_pFilesystemWorker->diskDevNameList(); ++ ++ FileSystemData fsData; ++ m_pFilesystemWorker->getDiskInfo(filesytemList.count() > 0 ? filesytemList.at(0): "/dev/test", fsData); ++ ++ m_pFilesystemWorker->getDiskInfo("/dev/test", fsData); ++ ++ m_pFilesystemWorker->updateDiskInfo(filesytemList.count() > 0 ? filesytemList.at(0):"/dev/test", fsData); ++ ++ m_pFilesystemWorker->isDeviceContains("/dev/test"); ++ ++ m_pFilesystemWorker->addDiskInfo("/dev/test", fsData); ++ ++ m_pFilesystemWorker->diskInfoList(); ++} ++ ++TEST_F(FilesystemTest, FileSystemData) ++{ ++ FileSystemData fsData; ++ ++ m_pFilesystemWorker->onFileSystemListChanged(); ++ ++ fsData.setDevName("/dev/test"); ++ ++ fsData.deviceName(); ++ ++ fsData.mountDir(); ++ fsData.diskType(); ++ fsData.totalCapacity(); ++ fsData.freeCapacity(); ++ fsData.availCapacity(); ++ fsData.usedCapactiy(); ++ fsData.usedPercentage(); ++ fsData.totalCapacityValue(); ++ fsData.freeCapacityValue(); ++ fsData.avalidCapacityValue(); ++ fsData.usedCapacityValue(); ++} ++ ++TEST_F(FilesystemTest, DataCDROM) ++{ ++ ++ QString strDevId = "test"; ++ DataCDROM cdrom(strDevId); ++ ++ StubExt st; ++ st.set_lamda(&DataCDROM::open,[](){return true;}); ++ st.set_lamda(&DataCDROM::execSCSI,[](){return true;}); ++ ++ cdrom.getCDROMInfo(); ++ ++ cdrom.getCDROMCapacity(); ++ ++ cdrom.getCDROMUsedCapacity(); ++ ++ cdrom.checkRWSupport(); ++ ++ cdrom.checkMediumType(); ++ ++ cdrom.cdRomGetTrackNum(); ++ ++ cdrom.DVDRWCapacity(); ++ ++ cdrom.cdRomCapacity(); ++ ++} ++ +diff --git a/tests/unit_test_process.cpp b/tests/unit_test_process.cpp +new file mode 100644 +index 0000000..9dcfe85 +--- /dev/null ++++ b/tests/unit_test_process.cpp +@@ -0,0 +1,70 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../src/process/process_monitor.h" ++using namespace sysmonitor::process; ++#include "../src/process/process_list.h" ++ ++class ProcessTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ } ++ ++ static void TearDownTestSuite() ++ { ++ } ++}; ++ ++TEST_F(ProcessTest, processListTest) ++{ ++ auto *monitor = ProcessMonitor::instance(); ++ monitor->startMonitorJob(); ++ monitor->onChangeRefreshFilter("all"); ++ ++ getProcessPriorityStub(20); ++ ++ monitor->processList()->getCmdByPid(2334); ++ ++ monitor->processList()->getProcessById(2334); ++ ++ qreal mergeBps = 0; ++ monitor->processList()->mergeSubProcNetIO(2334, mergeBps); ++ ++ qreal ptotalCpu = 0.; ++ monitor->processList()->mergeSubProcCpu(2334, ptotalCpu); ++ ++ qreal mergeDiskIO = 0; ++ qreal mergePreCount = 0; ++ monitor->processList()->mergeSubProcDiskIO(2334, mergeDiskIO, mergePreCount); ++ ++ monitor->processList()->getPIDList(); ++ ++} ++ ++TEST_F(ProcessTest, processDataTest) ++{ ++ const ProcessData data1; ++ ProcessData data2(data1); ++} ++ +diff --git a/tests/unit_test_service.cpp b/tests/unit_test_service.cpp +new file mode 100644 +index 0000000..b96221a +--- /dev/null ++++ b/tests/unit_test_service.cpp +@@ -0,0 +1,114 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++ ++#include "../src/service/servicedataworker.h" ++#include "../src/service/servicemanager.h" ++#include "../src/service/serviceinfo.h" ++ ++class ServiceTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ m_pServiceWorker = new ServiceDataWorker(); ++ } ++ ++ static void TearDownTestSuite() ++ { ++ delete m_pServiceWorker; ++ m_pServiceWorker = nullptr; ++ } ++ ++ static ServiceDataWorker *m_pServiceWorker; ++}; ++ ++ServiceDataWorker *ServiceTest::m_pServiceWorker = nullptr; ++ ++TEST_F(ServiceTest, refreshServiceList) ++{ ++ m_pServiceWorker->refreshServiceList(); ++} ++ ++TEST_F(ServiceTest, ServiceManager) ++{ ++ ServiceManager::instance()->isSysVInitEnabled("apt-p2p"); ++ ServiceManager::instance()->getServiceStartupMode("test id", "test state"); ++ ServiceManager::instance()->isServiceNoOp("test state"); ++ ServiceManager::instance()->isFinalState("test state"); ++ ServiceManager::instance()->isActiveState("test state"); ++ ServiceManager::instance()->isServiceAutoStartup("test id", "test state"); ++ ServiceManager::instance()->updateServiceInfo("/org/freedesktop/systemd1"); ++ ServiceManager::instance()->normalizeServiceId("test.service@"); ++ ++ ServiceManager::instance()->startService("test.service"); ++ ServiceManager::instance()->stopService("test.service"); ++ ServiceManager::instance()->restartService("test.service"); ++ ServiceManager::instance()->setServiceStartupMode("test.service", true); ++ ServiceManager::instance()->setServiceStartupMode("apt-p2p.service", true); ++ ++ ServiceManager::instance()->startService("apt-p2p.service"); ++ ServiceManager::instance()->stopService("apt-p2p.service"); ++ ServiceManager::instance()->restartService("apt-p2p.service"); ++} ++ ++TEST_F(ServiceTest, ServiceInfo) ++{ ++ ServiceInfo info1("testname", ++ "testdescription", ++ "testloadState", ++ "testactiveState", ++ "testsubState", ++ "testfollowedBy", ++ "testserviceObjectPath", ++ 1, ++ "testjobType", ++ "testjobObjectPath"); ++ ServiceInfo info2("testname", ++ "testdescription", ++ "testloadState", ++ "testactiveState", ++ "testsubState", ++ "testfollowedBy", ++ "testserviceObjectPath", ++ 1, ++ "testjobType", ++ "testjobObjectPath"); ++ info1 == info2; ++ info1.getDescription(); ++ info1.getState(); ++ info1.getSubState(); ++ info1.getFollowedBy(); ++ info1.getMainPID(); ++ info1.getJobId(); ++ info1.getJobType(); ++ info1.getJobObjectPath(); ++ info1.getIsCanReload(); ++ info1.getIsCanStart(); ++ info1.getIsCanStop(); ++ info1.getStartupType(); ++ ++// ServiceInfoList list; ++// QDBusMessage reply; ++// qvariant_cast<QDBusArgument>(reply.arguments()[0]) << list; ++} ++ ++ +diff --git a/tests/unit_test_utils.cpp b/tests/unit_test_utils.cpp +new file mode 100644 +index 0000000..c28c282 +--- /dev/null ++++ b/tests/unit_test_utils.cpp +@@ -0,0 +1,89 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#include <gtest/gtest.h> ++#include <gtest/gtest-death-test.h> ++#include "../src/util.h" ++ ++class utilsTest : public testing::Test ++{ ++protected: ++ static void SetUpTestSuite() ++ { ++ } ++ ++ static void TearDownTestSuite() ++ { ++ } ++}; ++ ++TEST_F(utilsTest, make_string) ++{ ++ char *string = "test string"; ++ make_string(g_strdup(string)); ++} ++ ++TEST_F(utilsTest, formatProcessState) ++{ ++ formatProcessState(1); ++ formatProcessState(2); ++ formatProcessState(4); ++ formatProcessState(8); ++} ++ ++TEST_F(utilsTest, getNiceLevel) ++{ ++ getNiceLevel(-8); ++ getNiceLevel(-3); ++ getNiceLevel(2); ++ getNiceLevel(6); ++ getNiceLevel(8); ++} ++ ++TEST_F(utilsTest, getNiceLevelWithPriority) ++{ ++ getNiceLevelWithPriority(-8); ++ getNiceLevelWithPriority(-3); ++ getNiceLevelWithPriority(2); ++ getNiceLevelWithPriority(6); ++ getNiceLevelWithPriority(8); ++} ++ ++TEST_F(utilsTest, formatDurationForDisplay) ++{ ++ formatDurationForDisplay(0); ++ formatDurationForDisplay(22); ++ formatDurationForDisplay(5); ++ ++ formatDurationForDisplay(20241219); ++} ++ ++TEST_F(utilsTest, getDeviceMountedPointPath) ++{ ++ getDeviceMountedPointPath("/dev/test"); ++} ++ ++TEST_F(utilsTest, getFileContentsLineByLine) ++{ ++ getFileContentsLineByLine("/proc/mounts"); ++} ++ ++TEST_F(utilsTest, getUsmVersion) ++{ ++ getUsmVersion(); ++} +diff --git a/ukui-system-monitor.pro b/ukui-system-monitor.pro +index e2999fb..dac1448 100644 +--- a/ukui-system-monitor.pro ++++ b/ukui-system-monitor.pro +@@ -2,5 +2,8 @@ TEMPLATE = subdirs + + #CONFIG += ordered + +-SUBDIRS = \ +- src \ ++SUBDIRS = src \ ++ tests \ ++ ++ ++SUBDIRS -= tests diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/0037-56-fix-sonar-security.patch ukui-system-monitor-4.20.0.0/debian/patches/0037-56-fix-sonar-security.patch --- ukui-system-monitor-4.10.0.0/debian/patches/0037-56-fix-sonar-security.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/0037-56-fix-sonar-security.patch 2024-11-19 17:11:36.000000000 +0800 @@ -0,0 +1,215 @@ +From: nil <zhoubin@kylinos.cn> +Date: Thu, 27 Feb 2025 02:51:20 +0000 +Subject: =?utf-8?q?!56_fix=28sonar=29=3A_security_Merge_pull_request_!56_fr?= + =?utf-8?q?om_=E4=BD=95=E6=80=9D=E8=83=9C/openkylin/huanghe?= + +--- + src/main.cpp | 4 ++-- + src/process/process_list.cpp | 6 +++--- + src/process/processtablemodel.cpp | 2 +- + src/process/processwndinfo.cpp | 1 - + src/procnet-monitor/conninode.cpp | 2 +- + src/procnet-monitor/inode2prog.cpp | 2 +- + src/procnet-monitor/process.cpp | 4 ++-- + src/src.pro | 7 +++---- + src/sysresource/memhistorywidget.cpp | 2 +- + src/sysresource/nethistorywidget.cpp | 2 +- + src/util.cpp | 2 +- + 11 files changed, 16 insertions(+), 18 deletions(-) + +diff --git a/src/main.cpp b/src/main.cpp +index 91f2e39..af3dab4 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -42,7 +42,7 @@ static void crashHandler(int sig) + char path[BUFF_SIZE] = {0}; + static char *homePath = getenv("HOME"); + snprintf(path, BUFF_SIZE, "%s/.log", homePath); +- strcat(path,"/ukui_sysmon_crash.log"); ++ snprintf(path, BUFF_SIZE, "/ukui_sysmon_crash.log"); + FILE *fp = fopen(path,"a+"); + + if (fp) { +@@ -51,7 +51,7 @@ static void crashHandler(int sig) + strings = (char **)backtrace_symbols (array, size); + + char logStr[BUFF_SIZE] = {0}; +- sprintf(logStr,"!!!--- [%s]pid:%d received signal: %d=%s ---!!!\n version = %s, Stack trace\n", ++ snprintf(logStr, BUFF_SIZE, "!!!--- [%s]pid:%d received signal: %d=%s ---!!!\n version = %s, Stack trace\n", + QDateTime::currentDateTime().toString().toStdString().c_str(),getpid(),sig,strsignal(sig), "2.0.8"); + fwrite(logStr,sizeof(char),sizeof(logStr),fp); + for (i = 0; i < size; i++) +diff --git a/src/process/process_list.cpp b/src/process/process_list.cpp +index 8d54ca7..9cddae2 100644 +--- a/src/process/process_list.cpp ++++ b/src/process/process_list.cpp +@@ -518,7 +518,7 @@ QString Process::calcDiskIoPerSec(qint64 nNewCount, bool isMerge) + qint64 speed = bandwith * 1000 / ms_lapse; + + char data[128] = {0}; +- sprintf(data,"%lld",speed); ++ snprintf(data, sizeof(data), "%lld", speed); + char result_data[128] = {0}; + int m_speed = 0; + +@@ -576,7 +576,7 @@ QString Process::calcFlownetPerSec(double lfValue, bool isSpeed) + QString speedPerSec = ""; + + char data[128] = {0}; +- sprintf(data,"%lld",speed); ++ snprintf(data, sizeof(data), "%lld",speed); + char result_data[128] = {0}; + int m_speed = 0; + +@@ -735,7 +735,7 @@ bool Process::getProcStat() + char *pos, *begin; + + errno = 0; +- sprintf(path, "/proc/%d/stat", pid()); ++ snprintf(path, sizeof(path), "/proc/%d/stat", pid()); + // open /proc/[pid]/stat + if ((fd = open(path, O_RDONLY)) < 0) { + return b; +diff --git a/src/process/processtablemodel.cpp b/src/process/processtablemodel.cpp +index f2661ea..c4c525a 100644 +--- a/src/process/processtablemodel.cpp ++++ b/src/process/processtablemodel.cpp +@@ -41,7 +41,7 @@ inline QString formatProcMemory(qreal size) + }; + guint64 m_size = guint64(size); + char data[128] = {0}; +- sprintf(data,"%lu",m_size); ++ snprintf(data, sizeof(data), "%lu",m_size); + char result_data[128] = {0}; + double m_speed = 0; + +diff --git a/src/process/processwndinfo.cpp b/src/process/processwndinfo.cpp +index b1859b4..372813d 100644 +--- a/src/process/processwndinfo.cpp ++++ b/src/process/processwndinfo.cpp +@@ -1,6 +1,5 @@ + #include "processwndinfo.h" + +-#include <QtX11Extras/QX11Info> + #include "kysdk/applications/windowmanager/windowmanager.h" + using namespace kdk; + +diff --git a/src/procnet-monitor/conninode.cpp b/src/procnet-monitor/conninode.cpp +index 1a2f12f..33074d1 100755 +--- a/src/procnet-monitor/conninode.cpp ++++ b/src/procnet-monitor/conninode.cpp +@@ -89,7 +89,7 @@ void addtoconninode(char *buffer) { + return; + } + +- if (strlen(local_addr) > 8) { ++ if (strnlen(local_addr, sizeof(local_addr)) > 8) { + /* this is an IPv6-style row */ + + /* Demangle what the kernel gives us */ +diff --git a/src/procnet-monitor/inode2prog.cpp b/src/procnet-monitor/inode2prog.cpp +index 3aa630a..b430a19 100755 +--- a/src/procnet-monitor/inode2prog.cpp ++++ b/src/procnet-monitor/inode2prog.cpp +@@ -153,7 +153,7 @@ void get_info_by_linkname(const char *pid, const char *linkname) { + void get_info_for_pid(const char *pid) { + char dirname[10 + MAX_PID_LENGTH]; + +- size_t dirlen = 10 + strlen(pid); ++ size_t dirlen = 10 + strnlen(pid, sizeof(pid)); + snprintf(dirname, sizeof(dirname), "/proc/%s/fd", pid); + + QString m_name(dirname); +diff --git a/src/procnet-monitor/process.cpp b/src/procnet-monitor/process.cpp +index 5b233d8..2f9a4c0 100755 +--- a/src/procnet-monitor/process.cpp ++++ b/src/procnet-monitor/process.cpp +@@ -228,7 +228,7 @@ Process *getProcess(unsigned long inode, const char *devicename) { + newproc->pid = node->pid; + + char procdir[100] = {0}; +- sprintf(procdir, "/proc/%d", node->pid); ++ snprintf(procdir, sizeof(procdir), "/proc/%d", node->pid); + struct stat stats; + int retval = stat(procdir, &stats); + +@@ -372,4 +372,4 @@ void remove_timed_out_processes() { + } + } + +-void garbage_collect_processes() { garbage_collect_inodeproc(); } +\ No newline at end of file ++void garbage_collect_processes() { garbage_collect_inodeproc(); } +diff --git a/src/src.pro b/src/src.pro +index b18cf24..d2d7344 100644 +--- a/src/src.pro ++++ b/src/src.pro +@@ -4,10 +4,10 @@ + # + #------------------------------------------------- + +-QT += core x11extras gui dbus network KWindowSystem charts xml concurrent ++QT += core gui dbus network KWindowSystem charts xml concurrent + + isEqual(QT_MAJOR_VERSION, 5) { +- QT += widgets gui svg x11extras ++ QT += widgets gui svg + } + + include(QtSingleApplication/qtsingleapplication.pri) +@@ -19,7 +19,7 @@ DESTDIR = .. + DEFINES += QT_MESSAGELOGCONTEXT + DEFINES += ENBALE_TRAY + +-LIBS += -L/usr/lib/ -lX11 -lpcap -lm -lpthread -lukui-log4qt ++LIBS += -L/usr/lib/ -lpcap -lm -lpthread -lukui-log4qt + + CONFIG += link_pkgconfig \ + c++11 +@@ -28,7 +28,6 @@ PKGCONFIG += kysdk-waylandhelper \ + libgtop-2.0 \ + libsystemd \ + gsettings-qt \ +- x11 \ + kysdk-utils \ + kysdk-qtwidgets \ + kysdk-diagnostics \ +diff --git a/src/sysresource/memhistorywidget.cpp b/src/sysresource/memhistorywidget.cpp +index c9d7be7..6e3f372 100644 +--- a/src/sysresource/memhistorywidget.cpp ++++ b/src/sysresource/memhistorywidget.cpp +@@ -16,7 +16,7 @@ inline QString formatMemory(guint64 size) + T_INDEX + }; + char data[128] = {0}; +- sprintf(data,"%lu",size); ++ snprintf(data, sizeof(data), "%lu",size); + char result_data[128] = {0}; + double m_speed = 0; + KDKVolumeBaseType m_KDKVolumeBaseType; +diff --git a/src/sysresource/nethistorywidget.cpp b/src/sysresource/nethistorywidget.cpp +index 675022d..79aa81a 100644 +--- a/src/sysresource/nethistorywidget.cpp ++++ b/src/sysresource/nethistorywidget.cpp +@@ -16,7 +16,7 @@ inline QString formatNetworkBrandWidth(guint64 size, bool isTotal) + T_INDEX + }; + char data[128] = {0}; +- sprintf(data,"%lu",size); ++ snprintf(data, sizeof(data), "%lu",size); + char result_data[128] = {0}; + double m_speed = 0; + KDKVolumeBaseType m_KDKVolumeBaseType; +diff --git a/src/util.cpp b/src/util.cpp +index 9f61a58..436ae0b 100644 +--- a/src/util.cpp ++++ b/src/util.cpp +@@ -209,7 +209,7 @@ QString formatUnitSize(double v, const char** orders, int nb_orders) + int order = 0; + guint64 m_size = guint64(v); + char data[128] = {0}; +- sprintf(data,"%lu",m_size); ++ snprintf(data,sizeof(data), "%lu",m_size); + char result_data[128] = {0}; + double m_speed = 0; + if (kdkVolumeBaseCharacterConvert(data, KDK_EXABYTE, result_data) == KDK_NOERR) { diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/0038-57-fix-debug-add-debug.patch ukui-system-monitor-4.20.0.0/debian/patches/0038-57-fix-debug-add-debug.patch --- ukui-system-monitor-4.10.0.0/debian/patches/0038-57-fix-debug-add-debug.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/0038-57-fix-debug-add-debug.patch 2024-11-19 17:11:36.000000000 +0800 @@ -0,0 +1,3352 @@ +From: nil <zhoubin@kylinos.cn> +Date: Fri, 7 Mar 2025 06:38:02 +0000 +Subject: =?utf-8?q?!57_fix=28debug=29=3A_add_debug_Merge_pull_request_!57_f?= + =?utf-8?q?rom_=E4=BD=95=E6=80=9D=E8=83=9C/openkylin/huanghe?= + +--- + data/org.ukui.system-monitor.menu.gschema.xml | 10 ++ + data/ukui-system-monitor/en_US/image/2.2.png | Bin 7712 -> 7679 bytes + data/ukui-system-monitor/en_US/index.md | 6 +- + data/ukui-system-monitor/zh_CN/image/1.png | Bin 94304 -> 78926 bytes + data/ukui-system-monitor/zh_CN/image/2.2.png | Bin 7702 -> 9458 bytes + data/ukui-system-monitor/zh_CN/index.md | 2 +- + src/controls/kchartview.cpp | 19 ++++ + src/controls/klabel.cpp | 19 ++++ + src/dialog/customservicenamedlg.cpp | 19 ++++ + src/dialog/onclosedialog.cpp | 104 +++++++++++++++++++ + src/dialog/onclosedialog.h | 40 ++++++++ + src/dialog/settingdialog.cpp | 120 ++++++++++++++++++++++ + src/dialog/settingdialog.h | 48 +++++++++ + src/dialog/uslider.cpp | 19 ++++ + src/filesystem/filesysteminfoitem.cpp | 19 ++++ + src/filesystem/filesystemwidget.cpp | 19 ++++ + src/kleftwidget.cpp | 2 + + src/krightwidget.cpp | 21 +++- + src/krightwidget.h | 2 + + src/macro.h | 2 + + src/mainwindow.cpp | 92 +++++++++++++++-- + src/mainwindow.h | 26 ++++- + src/process/process_list.cpp | 37 ++++++- + src/process/process_list.h | 1 + + src/process/processwidget.cpp | 33 ++++++ + src/process/processwidget.h | 1 + + src/process/processwndinfo.cpp | 22 ++++ + src/service/dbuspropertiesinterface.cpp | 19 ++++ + src/service/kerror.cpp | 19 ++++ + src/service/servicedataworker.cpp | 19 ++++ + src/service/servicefileinfo.cpp | 19 ++++ + src/service/serviceinfo.cpp | 19 ++++ + src/service/servicemanager.cpp | 19 ++++ + src/service/servicewidget.cpp | 19 ++++ + src/service/systemd1managerinterface.cpp | 19 ++++ + src/service/systemd1serviceinterface.cpp | 19 ++++ + src/src.pro | 4 + + src/sysresource/basedetailviewwidget.cpp | 19 ++++ + src/sysresource/chartviewwidget.cpp | 19 ++++ + src/sysresource/commoninfo.cpp | 19 ++++ + src/sysresource/cpudetailsmodel.cpp | 19 ++++ + src/sysresource/cpudetailswidget.cpp | 19 ++++ + src/sysresource/cpuhistorywidget.cpp | 19 ++++ + src/sysresource/detaillisttable.cpp | 19 ++++ + src/sysresource/lightlabel.cpp | 19 ++++ + src/sysresource/memdetailsmodel.cpp | 19 ++++ + src/sysresource/memdetailswidget.cpp | 19 ++++ + src/sysresource/memhistorywidget.cpp | 19 ++++ + src/sysresource/netdetailsmodel.cpp | 19 ++++ + src/sysresource/netdetailswidget.cpp | 19 ++++ + src/sysresource/nethistorywidget.cpp | 19 ++++ + src/sysresource/netviewscrollarea.cpp | 19 ++++ + src/translation/ukui-system-monitor_bo_CN.ts | 140 +++++++++++++++++++------- + src/translation/ukui-system-monitor_en_US.ts | 119 ++++++++++++++++++---- + src/translation/ukui-system-monitor_mn.ts | 76 +++++++++++++- + src/translation/ukui-system-monitor_zh_CN.ts | 76 +++++++++++++- + src/translation/ukui-system-monitor_zh_HK.ts | 76 +++++++++++++- + src/trayicon.cpp | 21 +++- + src/trayicon.h | 1 + + tests/main.cpp | 19 ++++ + 60 files changed, 1587 insertions(+), 84 deletions(-) + mode change 100755 => 100644 data/ukui-system-monitor/zh_CN/image/1.png + create mode 100644 src/dialog/onclosedialog.cpp + create mode 100644 src/dialog/onclosedialog.h + create mode 100644 src/dialog/settingdialog.cpp + create mode 100644 src/dialog/settingdialog.h + +diff --git a/data/org.ukui.system-monitor.menu.gschema.xml b/data/org.ukui.system-monitor.menu.gschema.xml +index 5f246d3..0301fd9 100644 +--- a/data/org.ukui.system-monitor.menu.gschema.xml ++++ b/data/org.ukui.system-monitor.menu.gschema.xml +@@ -10,5 +10,15 @@ + <summary>Control is support service list</summary> + <description>Control is support service list</description> + </key> ++ <key type="b" name="exit"> ++ <default>false</default> ++ <summary>Directly exit the application</summary> ++ <description>Directly exit the application</description> ++ </key> ++ <key type="b" name="inquiries"> ++ <default>true</default> ++ <summary>Inquiries settings</summary> ++ <description>Inquiries user settings</description> ++ </key> + </schema> + </schemalist> +diff --git a/data/ukui-system-monitor/en_US/image/2.2.png b/data/ukui-system-monitor/en_US/image/2.2.png +index cc94efb..57700e7 100644 +--- a/data/ukui-system-monitor/en_US/image/2.2.png ++++ b/data/ukui-system-monitor/en_US/image/2.2.png +@@ -1,34 +1,22 @@ + �PNG + +-��� IHDR�����Y���%х���� pHYs�������+���IDATx���i\����L Hd� �(� ����Tm�EK]Z\�[���z�������R{[�7D��q�Xc�b�WE���R\�$,���bZDA����Ι�9� �3g�0<�����ԭ����|� ����ls7�����������`qs7����닋����9�k��s�eYsss�L&���-�/�mhz�>77� �˲r�� �)�$@3(..Ff�'�q\qqqs��ł����˛� ` +-�Fhb�M���CM�(�Fhb�M����FAl���0 +-b����Q�����������`�&�������*��n߾�V�5�V��J�...*���ѱ������*�� ''����Dx�?u�����U*������]~~�F�Q��^^^~~~�_��������|z �!%%eɒ%6l���l��>%NNN���Ƒ��]���2�l�ĉJ�� ����STTԹsg��7oޔJ����u=�M��`�N��~����ӭ���-�[�nݺ���Gll,���S�ŋׯ_OD#F��ׯ��kv����ӱV$�3%:::,,����`�����������?�QD"QLLL@@@�.]jeee�;,,���#6@�ܾ}�����3S++����m۶)��G��KKK:t�֭[-,,�jupppLL�J�zjm0A�~�i=#4O�3�Lqqq]���:t��(7atpp���oY��>�$d�ɓ'�m۶��#6@è�j�JU;3 ���T*�Z�;vl������t�U�V ��<v�X���pWVVf�������R)������***���̬��:�N�כ����Z�g�s�����aaa;v���Ue&WW���+���a4���K=;�k�N��<��V��j+++��t�֭*UVV�رcРA +-�bڴi������۷+�J__߽{�V�k۱cDze�233'N��P(._�,�vѢEݻw�ի�|���]u�����k�������cÆ �[���M�6S�L������4>3b�4�V�����g�\^^^��z^y�"Z�pajjj�iF<ϯ\�r���˖-;r�H�=������(66�ȑ#���qqqaaa,P��£JJJ�y�!C�lٲ���%33s��ṹ�[�lٲe��۷�ܹSu�������+V̙3gժUIII��j��s���%44tϞ=�g&�I:�h(�T���ߺu�v(((���}d=���111˗/9r����g̘1`����s��EDD�����у��t钘�x�����А��)S�H$"������/�?���+�y�ڵ-[��=Z��7n�(�R����DU ��/BBB����/""�ܹs� z���4��&��AU]�bƯ*��� ����h�M7n�0r�&�Ju���cǎ}��7�'O�6m��ŋ���SSSe2�H$JKK�lӦ͵kH*�ѝ;w��Ҳ��d2ٍ7��9`������C�-_��jV��DD�������:tx�W��V�D��4�C877i�$�av��%���p��F��]RRb�T�ժ�j#k.�;p�����o����������_}��A9x�p�{��}���>>>��y���N��]E,��۠p>���gff���^YYY�v� ++��� IHDR��R���f���NG7v��� pHYs����������IDATx���w@g����l�.��*(6�PcQ�WA��&Xλx���ޙ;Mr��^TbL1EC���٢Hl4EC(*�(��RvYvf�?���(V�����y淓 _��FE����.Jō{/��������е�"-~�0b���@�W[�E����0��.�����~�}�zJ�R��j�V�!yxV0#�H������;��h&y� J�R��tv!�OH&�) ++�e;��� �>��S^^^__��U���L&�����*��70��_T*2t�F�Ra�@� ���Z��%�t�Z���W���V����:�gq�ԩ7�|����٭����֭ + ++z�5�<�q�#w��>��RRR��%�t{{��.�6l؇~������.,_��̙3�?т�,Yҷo�&����+V�����0���.///66�ҥK��� ++�b����g�vvv����]���&����߹�'VZZ�R�#����4���,Y�x��͛70��199y�ҥ����x�`��1��ccc�92mڴ��[XXTVV�<y�����G��7o�0�[�V����X���h�>}����g�����\�hQtt�.h6d�������>��_���YYY�~���������hڴi�ƍ[�b���Ɍ3Z:���>33���HE[[[OOO��-�ƍW�\ �����1`����訨���h�V�X����@o���;v�O>y8�)��7Μ9sРA/s�IOO/++�ի�D"�s�NJJJ``�ӯ������ټysTT�(�������Vll����[�333�:u�={֬Y��VQ������=<<���� o=�7��ھ.���1��u_�e=_c�}���222-Z��~~~qqq�nb��̬���G��wE�d2ݦ����~�������������D����������� 4H��w�}7`��������1c�0s�ʕ{����r777www]�w�ܹz�jmm���[���;��ti�O�zF�]+����/_��j�,Y�e˖Vn(i���TEE�B�heGGNJ��������<y��ֶo߾vvvDTVVv��Yww�>}����;w.88������\7|�����́�:�|��������T*=q℉�����Z�V�T '���qss������y��lll:���4�����o4D�M�6EEEmݺ�@��=�P(�J���uK;ZXX�r��Q� + +-�ر���khh�}��^���b� �������+666 ���tZ�6&&F�PԳX�Afff��� G�}���۶m+��ϝ;'���nѢEZ�����D���T�Tn�DaAAA�Z�&/+++222((�jxIHN���'N���Su�M��`~~~D�m�6�Jծ];�\����� �Z�T*��ӻv�Z��v<��۷��ǧ}����^���۩S'"�{nn�����?*//�СCk֬2�q������@.��T������Pa���9��q��yg2��d2����;t�`��?���dO~��7oFFF�X(���uʔ);w��k qBl���0����R�T��gΜ)//���utt�<y�\.�ڵ���ǍWOr���ݻw�g�}ޭ[7�H�����/��}}}CBB-Z�d��RYTT��O?���-[��С��Ç{��UQQ�w�ޓ'O2��F.Y�d̘1|��0}�СC�;w + +-zZ�@sx��Q�&N��gϞ�o���G���|��ת��U���:s�L���UAl�����hpMK�q�Ɲ?���ԪU���ȝ;w������D���ӷo_"bYvŊ;v�X�pann�T*�:ujyy�D"ٸq��;d�ww�ٳg;88\�p������'..n�ʕ�F�"������9�x)��&��vvv�,�R�2����ࢭ� ++�^���?���{{{ggg[YY��ݛ��ryRR�R�trrrrr�������{ �888���Qvv�F�3f�T*mr���@�T*�b~~~yy9b�<%��ɫV�j��}�݅~��G--tn������'N������L��e]\\\\\�\�r��5�R�V������}���ZmfffII���E]]]�w"���龨��255}8��/kk�a�a� �<R�Yugkk{� ��7�5##��ֶ�g�y~�ڵ}�Q�>}�lذa�ʕ�zd'�}���fϞ�������^j���R�k?���cu�t899龵���v�Z}}���������?�x���T�Z�[����y��͇;433+**�j� ����P�kݺu�/_����������X@@@K����_������G��z�����FFF�7UUU���C��{��w/99������Q��7o���YYYyxx�?^"�888�<_[[ۻw����������f3���^�~� ������ݻ�������:��k���\����@͛7o�Ν�f͚9s��������۷���v��9dȐ3g�\�x��������G�������MDvvv����9882$++�֭[���...D��㓞����lkk۳g�f�����ȑ#�\����fdd���ڹ/�xx9�~�������gϞ����� ++__߹s�v����ŋk֬y�w�M~��r6�����_��ŋ�����;�tv!�<�>�����_��+A��+X��_�A�����@�H$��ύxv�a7��?���������&���N���_������4Mg�.2���ظ������*"��#�R�D�g�L&S(,�vv!���}�zJ�R��j�V�RxV0#�H���0��������������>����������`�����b����A@����0�}��������� �����>����������`�����b����A@����0�}��������� �����>����������`��@e���2 ++ŲQ�wv5]��%Ң��ή��stt�u�Xð,+��LMM�Rig�����}�.��ċ�]��Qy�W�T*�J�P���vvE� �N�]��I�T�d2��AW������ڢ����Ҳ����0�}`p2 ++����M4Mg��Б����� �@����%�t$�>08�o��H�W"t)�}��������� �����>����������`���:of�K��I��}�+0�9fq7k���MF�ΐ�:�_W�c�ϐ����2,,��|���^^^���O�����>�`Μ9���T*������;]�}���C��ׯ_{:�y~͚5�V�R(U����F;3�&J�_�~�G��H��c.'"��þ���ߥ-�}�z��C��ق�"�|����5��>�o� �S����kOv�co�j�رcG��v�چ�����۷��ں��W�^}��Y"����߿DD���;���D��;w.X����J���ۓ��<==�͛[7]�{���8� ����8���e�����###gϞ={�l]�F�9y����Ӊ���ۥ��Mѫ�]VV7eʔ�����ٳgO�0a� DTUUu�̙��"z���u��>u�!�&MZ�xq����ᇈ�����t>�>�G��j����s�����^�X\I5��w�����В>���+�h���̍���ⶤ2����@��q�s�=uǜQ��ɓQQQ��W[[{����;v��ɓ'k4����e˖mٲe��Y\G����j��?���L&{����^��`����X�B�{�n�Z�lٲ������K$���p�����ׯ���wH������ ���*�q�>����j9r$""���\�� [�n���kء��<++K�V54���Qtt�\.'"��/��ҪU�Ǝ�xO�C����!?W�@��?����m�\g�u1�z3ө�37"�iW- ��䗊��TR��x��#���^������������ѥK�LMMu�����ƦW�^DԿ����.�y�;q�Ą X�-**JJJ��������뗖�v���ɓ'ϝ;�!��;w.333<<\.����'&&vH�E��ѣ�/ްaCnnn��I��j�<�gϞw�}���������cƌihqvv^�lYlllrrrCcuu��������#D�����蘑�1x��ߧ~�=��К�)�]���,������h�=U��i~t?�ނ�-��oU������v�P.xK}���d����+ñ�vC��D�TJ�8����[$�}�/����(�Ki�����/�x��z��ӊ@nPOV+�箉����j��N.�ƥ��1������=§������A����zWؒ$d��}�;�r���q�eN�Y���� g^$"**�92t�#/lXXرc�t��ԩSaaa{��!�����~���w�ԩ������h4R����l�bmmmll�{����/^^^���?r�\. �H$�����;��hBCC��åRibbb\\�R� }�嗥RiUU����������G�Q]]ݤ�a����;v���6,22���J�}��:tH.����L�0A&��?~���D�R�����TW���gNN�>�Z��~�zJJJTT�ngg�o��v�ܹ���999~~~���.\x��q�x�+**�{�9]%�����ѫV�JIIi�暚Q���?VWW���L�>��ؘ�<<<rss��� ��&�s_̭�������K���^�g�5N��m��M�m� q���B���\"փu�g_T�����܊����k�K�_�f �e��~�=�K��h�y^&���s6����3�r������8vI��6�9f^ �?�ϼ+wg�%DDv ++�.z���[e����#��`�JM� ++DTRE.6���=|�����b�\~�ĉ 6�b_PPЖ-[���<==EQ���;iҤ&ǖ��������edd�����Oҵ��W����/�իWtt��;w.\X__��'����Ι3GŘ�����9s����":v��������?����ܹ�e�W^y%66�����ׯ����s��0�ܸqc���-�:u��#�[���ٳ;v�X�n�D"IKKc������T7����dkk{���������o�����AW|ff�n�����u����YYY�(6�z2)))C����<x�-[�>ϫ'W���������Lw�m۶���C�yd�sss�:u�#�J��͛���t�,�^����ل��?W��]1�;s���d�x���D��5���MiJ��ǒi�����L�n̺���E"�~��hO��'[0⨿5s���:2�HGn���D)�����1�LoG��|l�@D�R�6��o%�\.�ɟ���y"�0aB<Y"�H$S9s�X8�� ˘�_�#��=��=~K������b߽*��S�>�B1v����d33�ѣG[YY��mll���~��OO�����W�496!!!!!������;&&F7IDݺu[�t�D"�q�������KDuuuo��VDDDEEE||�'�|���AD~~~� |�����~~~D��矿��+�)�J�D���������-{��9r�no s��-))aYV��������O7�VYYID���Dddd��[o���;۶m���������!���?��[�nmݺ���!<<�����x�W�պ��8v�X@@@AA�B�())i�<��\���Z777]�MMM=w��g�}֖4����pK�k���~�����K$[[�GFF����EA�+S&�� p0��0�K�EDD7�D"r2'U}k�M��0Dt��o����Vr��1��fr2���[�͆!��;z�tG�F�ǖ~.'"��e���^�I��R��}�����#�p]x7�/��z^4�5�yY�8���j"#M�-&�UPPЎ;���_|�������K�,�3gNJJʨQ�lll�8s�����?�a���us�w��%��={��uk㊋���ˉHw������JeLLL�yd��_{�5GG�իWw��-22����ᖬ������'O6X]]=t�еk�n߾���|֬Y!!!�YQ�ZmaaAD����v����V([�l��\}###wwwwwwQ7l�&�H�j5�zh����������;v�Z�>ϫ'W[*��4����ĉ ��8qb߾}��,���<�WWW[ZZ�T���i�gb@��=��j1���gM ܟ5����jÈD?��;��R�έr���1�k~M~o�p�����z��q#�>8P�}����E"�sbr*D"�qb��jYk��p�x8O�g��o�2�[��W��ޜ!"K�̙��t�f�V<8�^�T�;��}^^^���?���ʕ+�������W�����Ǐ?�c�t+�nݺ�c���#"{{{]~*..vss��iaa!�����6S�8n���^�t�{���������1bΜ9M�>t��!C����OK�.������fY���\W�(�,�*�����Ǐ�Y��� + + +-D"Q˖-k�t���|[[��g�*++�����RX�����͟k��/@SBlh�M�X��� ����0 +-b����Q�����������`�&����� 64㯜��H�M�r����ܼ�����o$�&���d2� � �,�(����a�K���닋����9�k��s�eYsss�L��41�&������4����Q�����������`�&����� 6���E�� �Ɣ]����bSP�@lj�oKrrr���999��MV�01�M��B�k���+� ���8N�Ֆ����r$'�1 ӱ�g��Jt(��3������n4|ʚ��9Ls7��+//o�&@#@l2������m�L>h���������`�&����� 6���� ����(�M����FAl���0 +-b����Q��������ϊ7z�'�J���|O�{�a������8^��E� ?���8��ŋ��$�f!n������bwg&��~ݙƹc��%s1������*u��W�X���3=���W�R]�Th�t:���?��ŵjժj�ݻwG�MD���b�Q1��""33377��={�=�}��O��Иnܸ����~�HT�������J������ڷ +-�z�jXX��R����6l���M�4� 6��hӂ<�2���m��T]a�=�+��cG�Wݘ ޢ���36=y�/�FCD)))cǎ�ژ��"lohUÇ +- +-��t?��cDDDtt���[c�[JJJAA�F�IKK�ڵk���F��;wn�>}���srr6o�|�����kk��`�&�s�8FufY��ùș�v��}��dYw,������2�m������mZ����e�E�V��JL�,�kF+���bU�&#&&���P����W����СCG�9eʔ�[����]�v�ا���������߯�B��JKKko�QI�������u:��J���C���� 7a�y>66v�����ާN�z�Jz��5t��1cƄ����_�JJJ���k��T��`���� b���)�S������pP�y�Gߔ���'���%�j���ܨ��&�~��e�B��$?Β�$�qb���-��0Q��3%'�HVIX"�S���D��T��7%3z��+�b�l�(N�-�!\r`�x�˃g�f�hw�xP;f_���7%��H�>�M���&�!��!91G1Nԭ���� +-;z����ׅ�q#!!��^����>acǎU�_^^>iҤ����j���z����/�Qnn� .^��e��B��{�Qee�Ν;�T*���j|f�[����_�PL�6-55U؞��1k�,�B�����7�TVV +-�srr.\رc��ݻ/\�0##���Z� z��P(�N����T��J����O�8Qu������`777__ߵk����=ޫ�����JJJz饗F���鞰B�BAD]�&�w��UO�<�&h��V�h�����9���Ӄw���dRZ0T�[�}R���y����SZ����q�!.̧�Ŗ�+E�#Y/���v���vk��|��t\�:7���'KD��qy%<%�s'��3��5*t��/���왨3�m'�D���Ԍ:80�����:��s��-�ub�����7Dt�}�n�i�� cS�`�s�����ϯjx 99y������� +-�X,���.]:y�dϞ=믖���L���O�^�j�Z�ys`` ��+V�X�f�ܹs���{__����Ç�---�1cFLL̒%Kbcc +-ťK��(##cԨQ +-�"!!a������Bz�y~�����هg���evv6}��w�ׯ߲e�ѣG����0��Ņ��O�4��ѣo����ٳ�xw��ݰ�0�'N�Y�&--M��6���IIIqrr�ܹ�����˗�\�� +-��m۶����������6A��rgY��39"J�������3��>�������o��9y���Zq�wycJ zk��RGs�t�"��~�z"��'�ZW�p��g��n��ܚ�K{�Ɇ�8��������D-���ݿ���n�t�ܗE�v����e苣��e�!��¤�����cW���D���gZ_\+++�o�>e��a����M�v��]��e����Y�f-]��]�vD���ҵkW��UUTT��������¸��ӧO���[U�EEE���kѢ�={v�֭۶m6ly{{}��>>>���QQQ�N�:~�x�.]�Ra���>>|��X�%"�N7������?�b� +-OOO"�ի��1y�ܹ���sջv�*T�����.[�,88X؞���s�Η^zI�����1���������ߴ?ny����?~���Y�.]ڶm���Խ{���SVVVZZZQQq��툈'''��ҧ��u���~xlm��U�E�|�M��38"����Ivჟ/�䉨�cdim�mk�� N�LD$d&"����J�Պ�ݛ]:H�qd�¨��ř�+��DD��tQ�9�0.V�I����9�DDvV��p��i���o}Y�9�Xf�����~�t��իWϞ=���W����2�L���t111�������� +-E�Ν����u��T�N�8Q��$�.�J��*}�W4Mff&����8p���IDð,[PP��O?)�����������������[�n�d����M�6�ݻ7??�*�6,!!���gVV�Pedd�����ۧ�E*�&''s�T*���V�Zu�ر��2��LDt��5�Z-������ �����oy +-������_�{����ۅ�&�������`�<6�6A�tj�ttd�(y��j��KɆ�̖V�X���R�Ҏ�(��P�5�"����5y|��DF|����u���Sp���͎єԌB:��oY���~]�������<�ӛVxrrr +- +- +-JNN677�:uj������fƌ{�� �z�jZZZ��� �3~���ӧ�,kkkۺuks�f�I$�?�T��-[V? +-���xzz&''���Ԩ\�[�r�ʕ+�o///'�e˖y{{�[��O>����ܢE�q��988lڴi͚5�gϞ1c���sNNM�>�F�z��e˖�~��{�������ϟ?|�p�������ܿ_��^�t�g`kx������$������c�U�i�{]�e�����Cl����0D �;����\���L��;�܊����ɢ�R��EDD�REklj$"��['��;4�a��P+�SQ)/{��DD���N@���?�{;p�U�>"��UuD����ѣ?��#�T�dɒڥ#F�X�nݕ+WΜ9�R��i���n����˘� �%%%U��EEED��� ����nݺU�!vvvD��W_ԮP*��?~�СǏ_�t�͛7�-[�0����J�:{��5kfΜy��"JLL4�2�\.�7o^``����gΜ�u�֑#G�;�8p`ܸqAAA�����������S�N�����`�K�����'�a|���V��o�����'�a��KճKߎ�NO��x#Kk�o_����Y���`�����`�\��Bf2cI\�km���ȶ�2��[|���K���$�َ�+�3�����d%&":w���/�Q�6&�KԷo��;w���ӧv���ǀ���&N�(L1y�����WmIJJ��宮�Dԯ_�����kG�t:{{{���x�^_�Ba.p�-ƌ3eʔ}��q'l��>>>�gϾp�Bvvv�N�d2Yrrr�Jt:�p)����ܹs��܄��&)==�ܹs�ƍ�!C�L�0a��qh,���u���~J�^m�p�aڷb�\�*� �$d��TR�N��8�4��%�Q��̶o�ĥ>��TO������Շ���3E?g�("P����ih7�F.�6I_���.�8%c.fz�6�L�_��2��J +-����p��I�p2ۘ�E���E��J+iL�ʂ�<a����CD�[3���ջ|/g�\L�M�YYY-\�P$UMC��e�ɓ'��������p���!!!����ܶm�3g�|��7n���'����ݻw���[�����ݯ��z�ʕO>�d�ҥÆ svv�0a�T*MKK+.. 9w�ܒ%K�}�]77�����G��=:??ҤI���������yBB������S�-�/_���C�X����O��{�>}"##SRRf̘ѦM�k���W��nb��ثW�� �����w���۷�����͕��©���LOO�' ͍���+77�`�?٫/4�&h��C��VO����ve�����F.���\B:=ťr���#u�����҈�K���/���O���h��*��YܽJ�H�� ��qy%�L������lC�o\ߎ�POv�'{����P��u���_Q�}~M�.6��h�ynNь�"K<���6��a�y4mڴzJ���'��T*U��/�e�+V|��7��NAA���۶m�^}�U����>::���?.v�ݻ��E�����<|��U��={��9{�l"�ҥKhh��ի/_�LDaaa.�������!�Xm����7oBaHH�����ի���F�)��aÆ���̙3'''G*�~��cƌy�'�����J�\[bbb���gϞ��绹��T�y�����9::>�q�� ��0u�;��ap5��P�o�5/�n��z?�?��O�:�2��Vol)ٚ�KK�r>_�-P�m�R_}��ZB��|��5S���lp�d%a�1��:����M�Wޠ�=��a�� ??�[�n�7on�$QYYYXXhooop������L��Rݽ{�x��q�3�����,,,��&(**���6665&w�[ZZZZ>t��^���˳���1��iprrzv�����<�T*�>��ݫ���������ߛ�L�F���1Dez������TPǣi��ͽ�:DD������Q��9h�T�BS���������ݻj`��H$��UW;���a�\^{{�붌�_$ �ơ�X���Y==�P���u�W]��P�M����6m:{��#G���,,Lk�t��G1�����,���n����}<�[XXxyy���O²���/�m2���&xz���M�4<�s���an� �h����Q�����������`�&�akajwF�0���4;����t��~��gT�� +-M���t��_�B�'��g˲2���[����t8ۈwN p��I���� ,�J�R�\.���-��n����Q0����`�&����� 6�������}!Fx2f����IEND�B`� +\ No newline at end of file ++z��;\�R�</�f�u�=RSS���u�Vݷ���_}�UG=���������F&��X�B�}�S�c���f͚�Ry����۷���t������O�z��Z���\��5�$� �|�Pw�PID�g*lLh�/w:K��&����[���\m��koGn���s��B��F�e6�������g+fD�a��*�Ǚ��!�(���c��bqj��0$�(ԇM�~��b>[��zuc�e �H�@�z"�����9�+���Gq�~2�ā=��v̿��f�5g2�t�m�:2�l����0���/o۶���lРAOг���/���_FFFj�گ��z֬Y���VVV�F�ڴiӜ9s�R�S�f͚��?�9&&fƌ�{�.))177���ظq���Ý��A���<ϯ_��q�D"�<yrTT�������F�)--=z����---������DQ���2��������Z� ������:ԫW/�����7nȐ!���w�4i�n�����9�'p�������o}||6nܘ�����DDEEE ++��ڵkUUU OHѫ���n����G-,,8�svv&��w���֖���T���<ccc����O�2��߿�����?�?�nj���P��������7�ce��x�ױ�ӷ�*����J��J-F��r,s*[��ӿ��p{n�x��?>\L��i�����!�(��7�2�s�_>�[:Fr�X8�#�}��>9�Gs��%�R�&=��f�xQ<M|7��� ++�p]����)��q��[»�y"J�)�ęH��LA.��>��ly�}�?�'����m�m?>��t̛7���^xaӦMaaa&&&O�-�0˗/߷o��͛e2YXX���ì\�r�111�$$$���x��� ++��СC�~������ɓe2ً/����{oܸ��ƦI���y߾}���]�v�ڵ���uܸqD�k�.�B����ˋ�� v���aÆI$����������.Y��eY33��[�<x���#�q��5L_^�|����ɮm�۷ogee��� -=z��ٳgrrrddddd�_~9r��#F�9s&##c���zx�u�1++���J���Ç뾞;wnHHțo�������oڴ������_��<^__�����$xQ�;���y��O:�=�e�a��kb[���Ёْ�4���͏�Ez�c=���<���K���m�R��2e��͛����ĝ菊��3f|��� w�������ر��%h������ϖ���/������o�}�iii ���?ڲ���c;O�?0�`�x��/ ��fc��$?6�\���D�R]�v-!!a̘1]#������ɓ�m` ӦM�m |}}�ZmNNN߾}�ӏ(�;w�쐧!<s��]��^u�Ó,C�焸��/����������=�슈�h���>|�c�vy,����}����%��ܹs������`p�?����I^h#����,�䅮�}��������� ����q�i�9'�����a�����Ɣ)RbI+�<˲�� �ف��� ��ڤ���]b�)>��A@��G155���:b�L�.&�G��V( ++�T��U�t$�>0D��ގ̷��B��F����0˲2������<����� `����� �����>����������`�����b����A@����0�}��������� �����>����������`�������:�����2����IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/en_US/index.md b/data/ukui-system-monitor/en_US/index.md +index 207f8ea..6a51f58 100644 +--- a/data/ukui-system-monitor/en_US/index.md ++++ b/data/ukui-system-monitor/en_US/index.md +@@ -9,12 +9,10 @@ System Monitor is a professional application for monitoring system processes, sy + The side bar/title bar provides interface switching and search box search functions. + +  +- + - Users can switch processes or file system interfaces according to their needs. + +-  +- +-- Users can select the startup user and process category to switch the process, current user or all users, or whether the process is application. ++ ++- Users can select the startup user and process category to switch the process, current user or all users, or whether the process is application.You can also view the total number of corresponding processes. + + <br> + +diff --git a/data/ukui-system-monitor/zh_CN/image/1.png b/data/ukui-system-monitor/zh_CN/image/1.png +old mode 100755 +new mode 100644 +index 40174d7..052209e +--- a/data/ukui-system-monitor/zh_CN/image/1.png ++++ b/data/ukui-system-monitor/zh_CN/image/1.png +@@ -1,284 +1,251 @@ + �PNG + +-��� IHDR���������J��]��� pHYs�������+�� �IDATx���w\����'��ql��DADp�G�����U�m���j�u�juۺj����֭u/T�"Cd˞wp����=P�>ߏ�6y��y�;rOy_b�ߑ�@C��DqN����hfdg"23164�$ o���ի����|�Z)Q��7�W=,�_��/M�i�$z=�x�A!�x4�+8 Wk�7<�L���wb�?P�1r ����a��9�LڵiM��g���S�f�x�~��0��[W�x�L%��ڸ�D!�z����&"37��[������,�� �����ܲu��Jֻ�7�˭,�:WGao�B!��A@7W��� O�����zg� ��������7��� �H��WE!� }*��B!�P-���P��~^yOS������1% �nI��>_�6�0�q���i\�B!�P3B��J�Z�2���'J�ۻ}+c0�B!������TYC0�4�i[+�l�_�����G!�j$x$�dQ��F0i(�kӺ�*M9vk�m�����XB!��ߖ���h.y�eg��W�Wi<7�5�B�P(t:��Y'B�A\.��������˂P�B����fd����B���(���X��4tAz5�h�Z�T�T*MLL8NC���Â����ب�w�m��"�� T�0�GM�F�)..n�R Ԭ����@T�ДC���NT���ů���-;\�'�B�A?j4�B��?�C�H�$����� @T�W�8���B��(��.B���պ��!�P]��t ]�j~�Q#w������W����b�ʕ={���2P�Jo��4������9'���j�i�]e��o&j�D�Na�=5�����DFF�d2�D���;n�8��.z~�Q#�`��m۶�kҥ����gϾu�֛��/��9s���G�����o������5�k��:ͣ��g��/;#]�Tp8>��_��h(������г�����kE��"��ۆ������#G��<y����T*�z��y�z��5a�����!&&F�������4M+�ʻwﺻ����T��L&�s�N``���qmBMP�=���+]dmm}�ڵz.�k���Y�����/{�fΜ9cƌ 6xyy����f͚�q��ڮ�W+�������Bc++�@ +- � IR��i4�J�P(2R�/���a�?��ZxC��?M�P�;x�`\\�Ν;�b1�" +-G�ٿ�y���5���5 �ڴN�KMMMLL$I������ ''��|���'���Ɩߐ��LLL�D��۴iS��P�ׄ"�F���cÆ ӦM۸q#{���^)�j�~Z�zv�������D"�@��p�\������M�D"I�4M���P+�6ށ]I��UL�V��d�eg<MMN}�c��A�_a��E^�����������47O��I�����rd�/˷���x:�v�w������ +-��p��R�t��@)/�I�V&f��V�r2���E�ֶY�Z�V�hec+a!Ը$%%]�xqǎ/�cdd�f͚�c�������W��L&{��a@@�������I����������l�_RRR~}�7�I��!�����ڸq����7nܨ��^/�j�~�����C����1CA:�N;Ȅ�P�-��Y6��i�'N=�����?2,��+%Ri����DZ"-V�������l��3ٝ��'=��{�g;?}b�� ��������9'�=ڸt�Σ��%�Ie��� r엳_,���`����ή���qe׆�Vh�����-�����d�g�t�����_�q����T}��U�vx�O�I���8B5 +-����ѣ_�5����#�9�p���fdd���+�J�a._�����<O.��P(�H$4M�]��4�F�z2�,//��ťB;��I���D5c�ڵ۰a�����y����U7��(�i)I$A0Æ���i���G����6��Z-���h4$I��$j� +-�i5�6�S:����٭u�K*�r�_�w�iim�R* ��?��_f�=��O�-+ˮ�Ņ��=ظt{{�g�����*� ��B.��������?|�d{疏��%F�FƷ�\�lQ�@s��G��ߺ^����j�oG�L�~]�J�R�y �h��#?)���f�(����h��v%B��������/�X�������t������cFFEQ����C�����B�HKKS����J��x�⋙ܽ{�BJ�^�$��BMT���o6o�GQ;�ڣYWS߯�hd�����:�N�R( +-��q�Z�g�d�R�X�P(�r��j�NG�dQA�F��v�nm���x��?+*ț�x�o�nC��s����Y�����~��Ą�W&}5?:<,/;��Č$�G��������$I>_Pɞ(�͎ �حg;{}��P����n�7��ݛWc"�9��[�ؿu}JB��;�Ba��_^Z���hJ�f�Z�V^R�Rbg�!�HI�R#����������Γelllll\ZZ��h��� +- 88����MLLڶm��������$((��Ȉ��Ǐ'&&zzz������Rell,��nܸQ�LJP�P?1w��6{��͛7�t��3gnݺ����_�ڸ_�v�EQ�N�cF�V�vѨ �����(�?��?�r�a�����ғ������IZ����S!��M�����<��W�(j��k����w��x�DKk�o��4%�ƅ�}�|8f������������v�]nlj6�� ��. 5V |�fվ3�@�T|7el��5��Z4u;���^^R���<}�`M!�P��H$2�����e+deeU}c��4Mggg��]����x�{�����!�!���ɉ�����]�tO�<IHH����С��gש��C5_aaas������ׯ�>}�������S���Z-�0lX��ru:���w���# �I+.��(�P�����r�����ʽ�Z�˧�� +-�ryO�@k/���)r�F#�U�ݿ+�q,�Ý2�]�P�ͪ J�|����.#?��a�v~�vo�h��ԲՋ{9��_q"�/\�R(��{���k3��sra�����=;4�����^E�[�Z��0;-/���;�О�߬Z�q�����O�����ܼ&������ +-�B�������ׇ����۷o���R�T&������ՋM�q㆛�ۏ'�X_$���?---<<��ryHH����u�ܹ��H.�K$������"�������s疏�~�駩S��ر��~��P};�NW��t&&&���y��TE�g~~���eQAEQR����goj���N�p��Ԕ;6���IA}h՚ K癚[�Z�#�w���r5jՙ��9|��R�b��Ņ�Ʀf3����؇�7�^��W�w������5Њ�{7.��|���_�ګ���î�9���F��h�|�s�&�$�ߺt^?��$^�P���������LO�k�̧֜�0�{���+�B��jJƍ�x��}�V�j�L&;|��-[*�6999**�$I6v�J�IIe�FP���˾�kii��!���V,ggg���������ZYY1���q���Ν;��V�B�Q�iyoaaX�Ҩ�(�7�EQK�,ٱcG���֬Y���ߞ8q��YQMܯ�j(��(� ��&=�����G�`ϼ֖a���'�X�.zF[}ܯV������G��\� )+.:�g�\&�?����ysV�# ������z���:v��g�yY�N-[������:;:���X�9���3�S�]ݼ�~>xLh``���{�-=�Zy��*`lj6o�������mYC��W��^�0̹c��t�OQZbl���`�R�v�V)c��BQ��.J��(?/�AA�����R^Z�Ϡ)�yЏ������!((h� �V�>_�SRR�x��N�:���U�������ybb�V���x�����0����������KKKv���������R��r� +-�"""B�ղ�a ��u�V]1�Go�&�Wm�ʕ�g�~��\+W�|�p8��g�V�( �e]�L�q?�0Z��������j��B� +-M��@JēyٶMQ�Tl�?lMM��/�:�������қ�>MIj�������ӧ}@�S���s�G��,��ۺjqnV�@(�2������+��������zz17+c�/>p�'��O�?��`��8vG�gQa�c6��qy˪%F�&Ң�.�}^����c�u�b������[���m�����u�,ZX��Z{gW�u�����0�G�ϰ�w���o�0�G5]&L�믿ƍ7z��v�����dddܿ���� +- ������}qC�P�X��ZXX]�z��绻��T����m�@ hѢ����J�������!!!�[�vtt,--������LHHx���B�AϞ=oݺհe`�!j�F�|������N�i�heEdr�̗)ݬA�H�53�]�^H&d��Y�$��HS��������iohd|��3�z�1���|ػ}�|�ҽ��3�{�7���%-� �0��w��=rn��ݐ�&���2i���s5%l���LK���zܼp��]����!-*8�QĽ�'����,��z����c��o�L�n�����=�}/�qla~na~nfz���s��ب�c��FE�@K��{v�������[��eg� %Qa���n����;��n����'�B��1z�h??�#G�<x���}���7o������X�l�ҥK�h�'�H�u�v�Ν�����kkk?�g�H[XX���DFFfgg��ۛ���/�J��{��{yya��zV}ܯ�h�ILL"�p8����,+��ݰh�Y��K��$�� H��p8ZM���H�MB����z�V>JV*�/_� +-�=k����@@PO�@3s��HKIO~bbn���a����U@�"�zx�r�\6ɩe���<�}��r������:`��J�4%��ƭM[�6m���@0h�X���x?/��ܪEAn�� %�O����]���KJ�����ő�!l&���<n�^�*�k�N��M�O�B58ww�J����]�t�?���b�OQTii�J��p8�( +-�L����0�\.��tr�<%%�����Ȉ ���t�'�nݺq�\��A��ֽ{�~���իW۶m���]� ��M5q?�Pb�N��r�|>���5Z��*)=�=�˗[89�#�k4�V��h���U�L��del]�8+=uޏ�Z��+�e}�;�r_��K�}���s��u��$H2�I܃{a������ح�B.��|ڡK��y�:t �q�{#?y����[��}���5������z����3L�̗��l�'-����*��]��C��q���^;w��q�ˏ<�B��h߾}����\�v�a�������Phii���oii�T*SSSSRR<x`ee���������JQԹs�(����� +-;v옒�RXX�v�W�G�z+L5��Plcc���HQ;��Z�V�T��d����Z�Z�0��W�TZ���iG'g�����t:�ƥ��*� ;�"Q��l� �WM3��?nZ��W�}�㮃w�^ܻi��[렾�vyqo��U�}���� ���ݾ�o~N��e�������eg�KK�ؓ��J�q����DZ%��c��F�+��c������y����p���߾9���Z�mGr8�ٙf�yY���~ �=d 6LOIҏ��0��ﻕ���B!�<p��w�}���������;200hӦM�6m4 ;����?��$ɾ}��[q�������ٹ^�!��c*���?q�vt ��9.6���P(4M����V���[�O�4�M�V��(*�Sg��zǯ��r��FQ���IQa���1���Z����oWm(�IEb�����-� -���?�����O>e��ֻjb��l���k�%���;7 %�~�&��g'�@l(��s��m�#��41�`w�?�C�w$����~�� ��~ء]�4���KǠ����?���Ņ��?7+��(��F�4]ؓB�Al�k��釔!�Ҟ@� �_�!z%� +-�ZF��'9\�?� +-gaN�s������#I�$I.�K�4�7�����սG�!#��y�;�,��Q$���9�V)����lkL�T�fe:���:�� E�\�ٲ�U���T�\O^RB3���8#5��PbjnAQ�����Ĕ���W7 �s����5�����������ٰ�5r<�V�?G��f6��S}�B�n��Nggoz�NNN����$I��������4-64t�����/��O��J��"�p95/��A��]������ښ�viU6.������kfiU�ek$���&�B��K�P-x�C��k�>��:�b��ҳ�_iQ�N�e�� +-��<����ų������`(�PSa``�T*k8b:B���Ǹ�ZDž�Eu��o�c�B���Ĥ��C�t��|��.B�Ap�'����E��s��� +-B���p8��� +-�B�P�t:|�5Ap�\��G�NTڟ��i>r�9����'�B� ]��B!�P#�ک��*�f��z��� B!�P� jҟOMr���#G��s�B!�0o�cPؼaM?B!�P�Qk���)��s�B������Ÿ�{釋�:B!�P�������=�a~-g^��b<����^��}��E!�j`D���c$�@q!������B!�,5���t6,<�!�B�AW�c��z��*!�BMB%q=Gr 8b����B��K`���Ú~�B�f����D���!�Bo���^/j,��n�o0B!�P=���u _w���a�Y<9!�B�T}��iAe#(B!�B���#�B!�����z���UGeƞB!��"����7����W���>B!�j�ނ�~�k�{�j̲���� +-A$I��|�X����8UTӸ_G�����R��i��&��[�+�A� ��B�#��w��e3G��L�@�h��.M�rg&0�{666 ]�f�a���J�R�422�� ]"��S���N*�D�P�����+0��C��]�� ]�jٟ�����"�� ���|>���F�B(O���N��H�ѫ*Ր"D!�x�C�ʣl�~�PM���.B�!�E�ċa���1.$j���4t�MG�h�B5��h�=��Z��B���7Q��ԼDeb؏����=���,��6�z�@�q?B�F/�q���^}?-Jm��!�j�ރB�)"����oUB!�j��B!�B�A�#�B!��1�%���D!��+��5���x�5g��-ø�-��æ��¬��+R���B����9ȗ{P'��a�;X}[W�0ZL_�%2��WW���6��)Gt�-mҊ�����R����{Ǐ��hLLL���ʯVRR�lٲ�>���ݝMٺu���G�^�ʯFQ�������I��YzJJJDD�СC�ҥKVVV���ʐ��ޮ];��T*+,�����((G�MKK�5kV���}�����Y��U*;�0���Ax�z=��|^[��dz3鐮�mH����� ���k��v�\�x�ˢ��t�t�ɚxߋ\{�*~~4s�v!�`�}�������;���$�)3�1ޏ�9��K� 7b\gN�k(���$`nW���dAHD�'c��Ǟh�P�����)��� ��~tcgN���9��T/�O�<���MLL���~�䉉�IϞ=mllΝ;7lذ�����pŊ����7 ���ag�r�ѣGW�ZU!����5k����wҤIlH����={�����������x�a�������GDD����o���� 22��ѣ�ܳg���kݝ�z�y�f�$;v�ح[� +-K�Z�Z���X����;AD~~��q����9�/����kbj;�2$ҥP�h�4�R0���/��H.?���V�W�6�RÜNb�M�^mɭ����w��^��%akJ�4�d��$g���[���|rH�&��Bu��(����FFp��=����3���@" �̈K�4۵h{G�PHY�%�� �IDAT�|\��ZΖ��pH"����O;���:��eϹ�@u��SRb߸g?KrlL*^��z�}���*���kG-=��_...vvvb�xݺu\.7''�]��w�}���K�.]�z�H$������;w�߿�������E%''�[�j�������fݺuӧO7442d�J�*))�(�]M�V����D"�HDQT˖-�B�B�ظq#�DFFN�0A�2�NP����7o�W_}% +-.\8o~���_���ۋ/�Ͼ����`mm��?�Ν;�\�3������3B��yY����X�p'� ���U���朡6���ҿu*��I���hkFX���L 3!D2J-0�����#a��at7[�����+.�g�0�c!�6���Nȃ�b�z|U� +-�#7ޢ�T��p�La�ղP~F��lYv���:�_�m�jZ������h ������w�=z����>|��=.��"��T*�H$�;w�O?�TTT$�����-[֥K[[�S�Nݿ����:s挣������ǎˆ�NNNK�.���8w�ܦM��� �NDEE�߿��o�8p����ʕ+W�\��sP��v��ʕ+'O�<x�`� Ir�ʕ%%%Æ �pʾ�������۶m����I�|���%K�wNNNO�<a�K�.�<����o��"[�M�dž�Gf����5�FC÷��5Ȧ-�� +-Y��i�p.�m���f�����&�3�Be2���4I��@bTr�i� �����-������ךTj�,$�X��ڔ]$],�Uv���1�� ��¦�8�%��������� _x���@ks��~��#bX~Rw&��^q#""JJJ� !!!//������62 -..�>}�dff����@ `��6��ݻ]ۿ���#��ܹs�7 �������d���w����_~��W�X�z������ٗ:$�˓��������cii ����gϞe�Q(��p2�l]gϞ�;w��]�>}��X�",,l�ԩ����```бcG�LVXX���}��Վ;zzz����[]�|y���b�X�9�g�^C]����^$���T �[��I�S�5�å����Cq�sD�+so?�O?���8�O�*��0����E��A�I7+"&��O:�����%GsB��bW!ԈL�H�s 'Ց�$���72��ٚ�0����Ly��|V�g����6 +-x �������\H-�<���ۉ�d�U��|.�~��ՙ�+e���Fz;��ܧ�n��W�\y��!�)�ʽ{�������!!!쬛��������[�n�ȑvv��(�J>����������������Qrr2��aW�D&&&� U*�R�LKKcs�h4���j�:::Z���� ���9�Z}���]�v�d��S��hѢ�q�D��?�|͚5'N�8q�|��r%����ݻw]]]�;��_j4����������{��a7���k���?��%2�A^����g�8ai�/�);cBY]3{+��sY�Ӟp�f&����L�ޘ���l&S��倀�B�$�K��*�g2�f��?i� +-R��B�-A�����˞hiD��b�j��B��`,�ʆ8��҄�� �U˶�Y۟cgJ���� +-;�#9Կ��3��O$6_���Ls�JBŽ���$�4�h!I�L�%�8q��pIXyJw2�i_NgϞ�N��|֬Y��Ο?���}�����={�d�u:��Ǐ�}�u�V� &L���?���B� +-��p�ܹ���������QPPGQԽ{�����(55�{����ƍS*�/^�p8�G���������J�6Cjr����;vlvv����&����{{yy]�vmذa3gΌ����������ҥK��o���Vknn������x�zu�E�.a�K��O ���+��ǹ�H��015���ݒ��M.&0� ��s�Ւ�؎lmE��0OR���)̉'̉'����-��<��T{�I~%����:�k^�n�r�PB.hup2���g���6�8���#�-I �c�]B ��%Z����S6 P���'�$���������+i���Ì�K�B��0����ȤR��rD|H�a��ć�I£&��i�����0���iiib����599����۷K$}������kv�,,,Z�h��?�[�N �d26�_�d �|��w�p�ƍ#G��T*���-[�r�<%%����~~~l�͛7�Pxy'N�7oދ%�ӧς��l�">��h�"vzڴi�Ć t:�� <�$����k���&�v�iii�hѢ�s��������yF��� .E��P���=ʮ�/��G��G�����8�b���.�9�>��v�;���J�c)��g���&+�Æp�l���'u�����T��A?B/� ��)�£t�߅��tB3��#�Gk"%���v3�l�e��Sp��>,���>�����p��0��Dzӷ-������d���R�"h����[��~vo���`cJL�����B��L������Ԑ�����!C����̘1����ĉ����ܷo�~}�@p��I��}?�8q��)S�����cƌ)((`_.o�رcǎ]�d���� ���o����1b�Bii����������}������]4t��o���}���t�v����oƣ����6��oooGG����w�y��:x�z%��`+,�5�B����V���)uх̨6䬾�{�����3�����r�it�v����'4�|@�n��`OY���D5n���Lg&�vbx��t�1}�'rݹ��lc�PC����j*&Hrde�|.a�_��E}��r&<��3�,=O�� ��!�����V-�QmI��`�r> |.�Mef�}V�:?�n���C��ø��b����5kVRR����@ hݺ��E�lmm9NrrrIIɎ;6n�hnn^u>S�N����@QT��M���ӯ]�6r��Jsؽ{���}�N�<x�駟fff>x������t ��...���o|� 毿�ҿA��ŋ�٠�����ܿpp�~��.��~����IIIyqx���Z���˚�����I�`� +-7��p�T�L�b@{���/{q�0���"�� s� x`��4쎬Y�!�<M ��)�7R��v���S��)���8��������ތ�~J{�,�f����� ?0����<l���:���!��$�1�� ��5io���ZG��0�V�$�� Ϝ.��%��]Q��,� �E�I$�}�����4�#G�l߾}ii�3g���� +-���c�>{��0����ݺu���xqے���/n߾=!!���ܖ-[&�J@��u+66�ƌӤ����`???v����(j����,�8��A��oߞ�f�+))�����Ĕ�����k���l�gϽ1�GV��,2���PUu������/{b���W�׆|�N������?c�q�d����vZ�Ÿ!Ԩ��@X��ĚSe=?K�ϙ���s�@{1�Y{�WYK.���g0l�����7��� ���{�O{[B��������o�Ǣ���&�f��ťBJAA��]�.^�صk�;w�L�4���t۶m�pNZ�vǎ��T*�oE�����&I�}W���#G����fgg�]����V�ZYXX���d۶m����[��:������&MzqPۦ�����ʊ�633��t�[�~�Lnܸ��v��!88�<#�j9�/R���О��#1�+ �߾Ñ)��=�P\�ϒLŤ�3�w�v�����_��!��C��t&���އ�{BM@��DV3�-ٯܰ�� �㺐c�����`�o�YA���0���Z-��w +-מ>w��ޑ�w�'Ih�@���q�}��;�8�f��� �b@�#`�@KC�������<��J�\.744tٲeNNN;w��2e����]]]�����9�Q�D"ф ��'O����p��ӧOw�֍��3�y��[�n�ܹ3##����ĉb����Sebb����}�����ٳg����_���U��DFF�]U@PP��$MHbbb\\\���O�>]>��յM�6���U��-�233���~���'N��x�������e������+v��e���j*���r#S���/�sZ�3��}��H�c�� +-������r�jKtv*���#y�ӹ���qs�I���B5W\p�"ODP y�$���$M��|�����\eť����|.0���+��߅�ʦ�0�D�k�e�|<mmBl�Pv��(!v}�e��TY�&�$ɥK��!��~۶mۯ���{��lX9o��ŊD��]��7�B&A�ܹS�����M�>�M���Z�lY�V�Z�j���'�����x|>_(�j���&.����hb���������v�ܹ)ƣ���lǚzlc� +-���Ȑ!-[�d���ݫז�ᰟ�yF� �DHb.��r�� ��W���k�,���p>?�SR����^! +-.(th)�蘿#��e�������Rrܞ�4ۻ��ڐf�մl&{1Q���u���9��N?W��`�p2��Tկ ���� +-��p (Ҁ�!p�WU������Dx^5��H+}� h�CB�K�^jN���@VVV�����@�V�o���T*e2Y�-^5[�a^�[�B!��˿�Zo�7h��<����R�PX�}�V[XXheeU��6��P���̎w���zT��g&�O������\L��㈯��L�>��qil_0����WX���6�(?�%�d* SQ}�R��lHV3|LZuw="���~9k�5��400��bY�ރ�x�o��<#����u�Q�Tm%B!�Bo�ʛ� �����nB�8jT�~�z�b�!GՈ�wQ����oUB��v�xUD�v��j�~�#��3�#��!��@?B�D5q����A�g����AU�~�B��FFF�aj$�����\'��r 6PC�ɐ_ŭ#�N�I�K��G���L���T��0B�@I�|>_,cЏ�j�~��T��:=#�Cڪ_��~ԄyY^�سO�ю��g��S���;;i��x��k��+1��Cڪ�:W:�)�!�B��F�vuv��;h���2BE��k�����=�5����U���fo$ B.ckĴ4��H|/!�B�Q��x�<�im�mm���ͪ��ZU��.��m_!�z�x��7�!�B��!��q��c�W�&���!�B5WüA�}�SB!�j"�U]�B!���7i�^�����e�B%�h�B!�z����C2�j�n��7��_}!j|,��xB!��.D�v>������~�B!���|P=��!�B��`�_k^��O�5�n��B!�zk`��:�(�m:1p-6�i:�B!��� ����ئ!�B��x��z��!�B ��b`��^�|o�qMrnX��!�B�%�@4l��4�ޟ�ó�t��^���D�!�B�P��|��;W/ +-D��=��$Y����TB!�P���z���V���8�#�B~���7/���|���xx�No��� �ɏ�>�|f�d���d��g�|;�'?Q+U���n�m+lx`��y9�� 9�p_��y���B!Ԩ���^�=�����r�3#CC:��f��o.�>���ל��:�r/�I��8�g���]_���+�9�O?�n��]~|��T~{g�տ�^>��S�z�^����V-\�ۼl_uރ~sm�����1 �B5��;����7yi���Ղ������n����z�ud��H���~<���Ms�XEV.�ܗoݓ��h�D6��x;}d���{��?�����%�&��Q��Ql�N������l�h�v�C�k���ŵ�v�o��A!�jp���zo��w�߶��l���,o����~o���HM�sr�y�\W ��P�R*��^G.��;�c��[\n`�;��.��x�����sV��J�~^��!�B�Ѫ��z�\�N��|����cljV�:ҢB��T��V�OfZ�/&��� +-���mg�<z,�r�����q�Vm� ��M��4z\���k�Otg엳Ć�Z94�B!���:����ٵKp�C��O����ғ���e���F�&��ܱC��3x��[�*2�v�R������_Yq�Ӕ�C����_(������A$�= +-z���~��;�����KKB�ϯ�v�����6�{oX�F}l!�B�Y]��9|��'�� +-��s���s�.-��Xةg���upZ�~{/�����,,���,%!���Sl�x���˧��_mݾC��'��������0���� S<����$Eܹ�k�j�J �bC��O��5pp��ů�"�%*�z�Ljm�B!T��*�K$��}�v�.�}��:hfau������g|��HT7R�J��j4�q1�)�Ķ���"���q��U�˧�� ����^l(��s�ص��������Pr����k�_��p��A4��fgd?M�������Z9�f�6�C@!�B�����5pȥS��t6���A���|[�R����d�g��ڴ�ݽyuܴ�1�}�����{#>���iiqa���~E�T=�������˭�A�z{��ƶi�Үr�BxB*�R�� +-��T�'�<!��Ca�$?�bֶ�u��] �Ҷ*�<��;�|>3-��څs��� �o�:�V� �_�]�&����߆ʧ)IvN.��iq�Ӵ^���Q�(�M5� +-��|l!�BMF�V�{��������&}�J��d�u2����O��w������w��om�Ȇ��-[-ٰ�]a��eҢ�w �B6���CG�mlj������Z<��f��OB���a�j#�6��^��L�v����8iQ����&���45��ޡ�Emlj�д�Ш�"����uۍ�N�5W�@��8��Uu�2D�Z�ӱ�������Z>�ȑ#qqq�������]��T�D�VGDD�<yR�V'� 33�ŽDGGO�81::���H��˗/8p�a����E�I��7;��݃���Km�}��j�58��u�0����a���ҥK[�la������ ���S�R�V�b����CBB*$*k� ������Oaaa�S�����Ǐ�l}�`�ie����|zAA����OT��uwP��N/k%%%�_��f?Ӎ��ݻ?~�N33k֬��� [�����=jԨ +-ߙJ]�~}���E�C��_VV���ˋ�� 99y���J�R�P� ����w�233G�����*rްaCDDD���a}�ԑ��k��1w%�&ۏ��v�舻Ey�됓�4/'���������JMLxo�ǧ�~��t�P��0<��M���>���Ғ�' "�X�TD��8|L��ۦ��?�8q���g��kYQ�w�>}���Gnn�+� ��� 99� QQQ7o�C�����裏*d���Z��|JVV֜9s�ryAA��[��D��===������t�Ν���wrr2dHIIɃ._��lٲ:?M��ի��ҪX��?�ҥˋ鎎�] �֭[�W�5Ǐ�7o^�ٖ-[}���nĈ4M�ܹ�O�>�&���{�J���7nԯ0z�hooov:**�O>Y�|���õZ����˦GDD\�v����Z�l����=z����T(Vz#Q�R鯿��?V\\���g�����_�U?;|��ٳg�������K�� ##�_�~���c�.X�`y�=���U[R+�����ѣq�ƽl�{���ڵk���5k7�xzz�۷��NMM]�fM۶m�و��s�εn�Z�aoo_�դ�t����NW횧N�b����C��߱c�bbb�������`�3f̈���6m��ݻ���ʯ�w�^�V���Ϟ�*j����w��ѻw�ɓ'WXگ_��>��� �:���:�z&��z����.�1)?'���ʢ� �ܼx���u���v�.-���ڰ���6�O���2������Kְ��� �IDAT�bk�E"���N[_�>�?�v��mfW��<u�T�B1y��������N��J������������T*-,,x<A� ]�bE߾}�H����ffe�m۶��MRRҌ3����b����&�T�����s�N�8��b��������ɓW�^�^\��P(ƌyvϩ��,X���[祑����H$l<QZZ�f͚�>������ڵk �_9<<���dYYY͞={֬Y쬙�Y�Hj�5�{��x�"�yxx���?t��e˖u�����Ǐ=Z�xqVV�D"144d��p�B�~���������kkk��(j�������g���s��)S�p��~���o�t:]ll,[�+ +-ٸ��̙t��� ^oܸ�e˖�>!�����j���i''�J�R���~������ &�a����۶m�f��ѣG_�zu���巺u떑�і-[�/V�Z������������@dd�@ (�"�����^�F� ~���_�+W�?�;q�D```ǎ@�R������ηo߾}�6�0���:t��ի��u#55���g���@LLL��5���...YYYS�L�'&$$����mڴ��ٹ]NJ����kג$ ��3 �ӵk�%K�|����`ii�ɓ'���s�С��|�8uꔕ��>�H$eC�;v�O�>���J���/�;q�Ċ+�Z�̙3�M�V�G����@���Џ�K&���Lє��IӾ�^lhhdb�v�ԳM;_C�A��mhd\>�Cn��N�#�F���Kg�����l ���$���+�P��={�d�-[��h�۷/������۳7�˗/�I�Z�����K�,<x����E��w�)�Z�xqtt��ѣ�� F�Y~����S�NM�6M�Tny�ڵ�����g�֯��y�ر#{� +-Y����+w���k����ر�{���,��d���mmm�q�?��C"���j�T���gffV�)Kpp0;�����ի�}�!A�������v�ܹr����`��_�����͛U*��������Ͽ��{l�[�g3����{�o�RRRj���chh>x�`�s/---�������S^^�0d+8��� �R�H$JIIy��R��r����4�B���VLZ�vΜ9���;v���o�a�]��222�'z������[q����p�+W���.]:t��V�Z������_~�e߾}������Ǐ�s�N�^��l�B���۷'M���b� +-�=�cǎ +-�s��)?�>ݒH$��=t�M�3f̨4O�7 �A=z������&22������Ç\.��ɩ[�n����\�p���k4�k��r��{�����z������w�>r�HBBBjjj�^� +- +- +-���z���>>> r���a.�Ө"]�(�k�V6��tg� +-kJ���+�z5츳|mh��iȳ����Ν�0̅�`ܸq�ƍ~����ٳ�?n``@�d||<��W&��<y2>>��;O�>��k���611��V;iҤ���������߿�mg��j7m�t��Ճ�̧O�^�r��>s�̣G�������&L�p���͛7_�~��O?�����JMM ��mILL�>S(V���Pe�ڵkWhh(;�J�Q��������V�.\�pԨQ���߳g�H$���{�>r䈽��H$JOOg�W&�ݺu������<00p۶m���4M��k�rrr|||lmm�0oo�-Zl۶����tѢE섁��͛7�b�S� +-Ž{�����o�^��G�ѷ��k7o�=z4�0@_-�y�f���}e���b�833��ㅄ��u�z�{�f'��~ٖ.]�t��Z)�V��5kMӆ���&MڵkW�����e���Oi#$�J-Z4g����ҥK����ڵ;t�ШQ���1�iӦaÆ���L�:�ڵk|>߾}[�lٱcGPP�W_}��?���7�ԊA��Ï?5jԹs��5�k֬a' ٻ�������m۶�m������T����õk�~��G���[����?�<}��Ν;{��YTT��?Ο?Ĉ����֧O�e˖��T�3i�q����[�n=}��-Z���[&�YZZ@xxx�.][S�j5�.�Y�l4��%++��Ç��;�����|>�����ё}x�����;����㓐B�Hi"����bg����kł�,ET�e��6@QQA�(�A�,H !�$$�����fC���<>x��{g&�|�̙3��3��pi4��d�X��� +-eѢE�#~�ՓL&�ݻWNNNNN�Ν;�֭spp���>t���ϟ��C���?~��lQQQmm�Çϟ?{!vvv�7�?KPPPPP��o߾�<�w�FBE~~����͛7�������FFF���T*�ӧO���zzzt:]^^��`�����t&�I����������� ��������B�������{�V?~��v����=))����ݻw_�|Y�pa```cc#|"�D���������PTUUL����ϟ�?�vh4ZAA������[��������***SSSKKKo߾=z�h���ӧ�~����X�"66�e���ĝ�W�X���{������ݻ��ܼu�;�,�����q�Ɵ����Z������[#��HII������_����Ǐ���wuuuww��x�(����߹sGJJ*44TYY9!!��`���iii͘1���{�֭mz��9�d2~������:�� +-<���<y���b������ g 155��\w4m�֭<�@ 9r>���ᡡ�ׯ_�r�b���?ʙ��� �7o�7���� // �����=�QQQ���عsg�E �� � +-��9Q<�.�7�\ZZ�`0���_�z���tznn���,��~��J�:������(,,�{&&&6l���hs8�ŢP(��X�p����ڵkϝ;�dɒcǎ�aC8���w�ލ��:t������Cbb�C���������7nLLL��V0۵k+������ƍ��|�N�ʟ���TUUEDD�>��^��o$<`v��mh��~�����CBB��ݯ]��`0X,֪U�233�?>t�Pww�[�neee�:u���qѢEÆ ���?eeey<ޭ[�V�^ x�:nܸ��l��C"��LfRR�ӧO���JJJlmm�?�g���deeihh�9��G��>c� ���VPP����ׇ�V�Z��p������UUUƳg� +-a�,8������充� O�<�%`qq�����dffVTT455=x������۷���[�l�R��Ǐom��&P��a�Pf������������F���t���/><@H �۷o_�lٓ'O���7mڴ�o�:99M�8��=cĈ\.w�ǏWQQQRRJMM=w��B144�s玖�����pv�p�������� '444::�{��ѣP��x��w�z{{8p��~�@RR�ł~��kwee�����۷_�~ ����f�W�Z����W�^������������m߾�СC�())y��YQQ�����766� ���/�#�^��zz�2���CCC���/^�`0\]]y<�� +- +- +- �n$;v� ��.]���c�ٗ/_�xyy��˿}���(������c���?����L�:uڴi���P(� ��r�0ͅlmmO�:����KII�8qb�ֈ�R[[+** +-?H�_��$�jnn���w��m}���b<� N'#!!=====}������ׯ_�q�t��z��M�8���vvvP����;vl۶md2YVV6<<������c������/��������x���Ν;w��I�����H$�@ ��������6��㭻�/_�^�~����ÇO�>�����KY�zurr�{������|}}�\����OOO.�;u�Դ����������"h��?:�Ʉ�\���n߾����b� +-�Q^^N"�V�XQUU��1G�7n0�.��D11�.�[���͛?<���^k0WeeeG�ٲeK{}b©������۷l�2555���������&"D[[{���ׯwvv655���>{�laa�U�N�8!##���C�q��1��O����}�������&777�Nî\�1����p�������믽��b�ԩ���QQQ�.��?n����������jkkUTT444|}}���UTTp/��/4���a����_�3ḟ��/^�X�|9�����\�pa���"{?�3())%''gdd���<}�TQQ155uɒ%ϟ?� o�nll���9|�p@@��C���QQQ~~~��@"���ʢ��bcc�K������Fnn����a:����u�����������_�:ujҤI������P�������<~�����1�����������0���/�Q�KUHyy��E�ڌ�x��=<����FB���*++<x���BJJjȐ!<HIIٽ{7���ㅅ�����5 +-ɲl�2���͛e˖��?fbb��������啟�� ��p�\�:�f< +-.�;gΜ�N�݁��Vdd�����-[��뛜�|��1�"""{��}��}kC���n�svv��ֆ�a!�{waa������===�^�XXX@��u�֩���X�W�\�r�J��T*588��Nؚ�}��D��}�� �dii)...pE99��q��1233I$ҙ3g~��ג�����k���3���$.���O����;���;v,���q<kjj6o�<}��U�VM�4iժU\.w�Νx����=z��p8��Ҟ<y�t�Riii�QII�Ϲ�C�d���AT����g2�111�Νk�@KK ���9::��Ĉ�����̝;7<<����:z��/ +-/]��p��aÆ�������;wnƌyyy�f]�����{��YZZ�9D�����v횳����Q@@���2� ��������I$����%$$^�z��Ǐ���0���������z���>>>���o�������g�5jԟ���_ �7��hnnf2�0p'4ɨ���"L��8;;�#��G�w�F��ĉI$n`����0���j͚5C��3g�������P&�رc�k�y��muu��3gZﲲ��Mkkk���(88�����۷0(dkLMMy<^����������ONN�u�XSS����b��|�W����'�rpp(//�z�*�fΜhdd4o+W����ߚ��������ӧO��?ƌӽ�� ����x���G .$,,lĈ�Y���x{{_�x1<<<;;{Ŋ,�ҥK�<�={��ѣ��٣���`0Ν;gbb�ǫ ^�f ���ddd�رCYYy߾}D"QGG�����?������{������˗���bbb�ܹs��p����!@�O����d2� �qP����Q�Fu�Q����}���ŋ'O�lbb"##���+))��+W�y�����Ç���}+R/���v �n�~�����U�̦w�� m3Y\\�ҥK�দ�o�z�*�������.KKK�?^FF& ����͛of >>��� +-�DNN��ٳ�7o旳���MMM�����%�{�\����0Bmm�������q��7n��KKK���:�l�]���`ffVVV�>��d29 `̘1...�=*//�r劓��ѣGa�4��ܹsժU�VTT\�~�����ݺu�+W`w��/_��6m���::���;�����x�5����������d2i4ZjjjSG566����~����b��Ÿ�P(T*_%��l��WWW ������yEEE�,Y��������a����5�(�'@jj���tB8�ѣG �L���������r����>���/^��c�����kmm���i=��/R__���9z�hWWW|���������Ǐ����'���������3g:88̞=� +-D��`v������������x{��d������Ν;S�N���HHH�����h ������ӦMݱcǬY�TUUmll��H] +- ����W��.M� G�j�ߵ��χ����?�%$$���p߀���L�0z�h��ÇgϞ ��<XYY��!K�,�URR:p�@�E�I^�xaddE�7y�ꕼ�|k'�~Fxx84�fff����ݻ.�[�n ���wvv�3�����?uꔶ�vzz�����ݻ���N�>���;���σTTTzrd'ʼr�JYYY;;;�8;;�Ntt���������---����u>|����mgg�'1bĶm۞={�h�"yy���j��w���666uuu^^^����v�u�k�H$��uPSS���&��}}}�����ÉD����ٳg�Lm��.�={$���2&&��˗�?��Ӄ�����'O��ǖ�����í!���D"���7�=Nlll\\\tt���gϞ�1�~�CE�וz��5eeeSSS8��{�����M����u��Y����3�@UUUJJ��ɓ��L] ��v�� #\���͵��]�d�ѣGϞ={�ҥy����֊���Ė���#G^�|���vԨQ��%%%pt���۷t:��ÇpuРAx�1���F��ZUU�� p��R����l6���N!?��N�����Ο?��(//g���1�L�7B�Ѽ��mmm�S��o$l�?~���uuu6lhhh�>}���8~����KKK��ASS3==����l6��ݻ�>}*//�s��Xiii���w����_tuu1������������8w��ٳga����������hkk�:�DsssVV����ǻq�ƬY�z&BEss�7N�:5c�8|YOO�̙3�Ν���>|����D�0lԨQzzz^^^������tQQ��ϯ���E�����쳳��q~o߾��=�Z����477S(�������Y�f� Fprr����]U������,���\DD��� +-N?���1b����ׯ��ׇ�l666�=������m-�����@���홙���`�����(4�$11���e۶m��X\\����֭[�hhh`���'??�7o��]%��x�⅂�BKKKQQ���ڻw�6odɒ۷o:�رcÇ���ݾ}��gς��rss7l����r�J% � ݏ�9��#''gii���(""r������/^����h4�E"�( +-�g��8�?�W����UKKK�������������F��+V���Y[[�?�J�y��̙3[�z��ծ]���p��ׯ_���k ��o�[())A7�#G�hii������-_�|РA���>���KLL�F���D�!OLL����D�ԛ��8`��]]]����|�� ee����khh�����'^�~}ݺu#G�9r�@����|}}a��1c��u=�۷o�����ٳp�B���h������eee0�)�@WWWKK��l6�Լ�5����"&&VRR��~8� T��k �@��� ������6�m|����n\�jUyy9�������_cbbZ�9x� ~x����AII t;!�mzs��|�JIII����8\.���ǎ��x4�I�&�����������������ͳ�� ��c@����,Yr��Y6�-""�l�255���8���`$&&nٲ����D"�֭[:::����������� �'�v`Fx]XI"��_���?�^��n+�N� �Em<B�| 0�^��ׯ_���:]��RWW� +-�Nojj�������� +-"����@ ������GCC�������G��~ +-���r���DDD��oWWW���w�F=C��3�����˷~:���;�����w��� +-a0������_�������455a&!!Q^^....##������%%%{~���+��_k����mii!�H����q�TWW���6gX��hGZZZ�ُ_8bbbx�B;���l@:���� +-.�ۺ?��㕗�CW(~{�ł+�D"L#"""''�^� !�|�VWWc&++cw������8'��� �IDAT�qq�&*��߽o�8a��a�b�����O6^z��*�+*�g~�(�5ZQ\\�u�;����L돐�hT��:��������u�������;�����m�+����6�Mz�M�7�<�K���Z�P�t��k�c`����N}��F��D�!1 +-��۷�����o�7q����P��B �����ǹ�W��?���㪝L���~�@ D�px��ؔ~d�Gt���@ ��AzM�w�4���ۣ���O��@ �ېzG�u����@7�/}�?+����@ я�Q{?��K��~�@ �~|ȿ�?����@ ����=�ބ@- +-A�T�@ ����H_��W�������@ ������������@ D_���G�:���@ �\��4��tz��+G�n*L��Q��u�@ �|�)���]�{=]�et�!�@� +-@ ")��� +-�$���@ z����=v0+=����"�h����}� +- +-���x��%B�(/�}���;)bb��'�o�~\ﶇ@hCL&��8sr�)5M��+�@ ч�.����@�-�A�inl���w��ȶ�';8�^ȕ�����]Ǽ ���q/���5�y\�#����~��voa������]O��|�8�e#۵�{����@ �bw������C����<.�ݼ�����w���r㦏�>u�|�@���ퟮG/\����,/3�2�fpqaAܣ���*ӱ�K� +-�:����Ĩ�ƣ��~���d�8�Q�F���NO���b�.��J��������5�@ =A���3ޥ '�I珻K��x��ܺz�����C�����j>~b{���ɱ��-l��Xe��s3?�];֯��wo�ج\k�b-~��/Ɩs旕|��~���O�9�\.��e��(#�c��G �*�E�x�<��W�@���s!����;ǥ���F�fYi�:����/yRR +-�*��M�<r3��O�}⬄�$���k�j7��u��%$��sS^$���lVzʛ��FYyE�A��o�jj0��Hy�����&f��wGy я@ !l��h?��Z��d�KflF�`�٨�}��&��e�f��31�z��=���s^.�D�?�^\B�SV�� MY9yYy�����%$��`67�KH����3Ғ_a<^c#/;���bTqU ͼ쌼��@eyY�nj��ʮ����[q�.Xw\Y(�5�r_P�xͽ��@ �އ�7��� ���BN[KW��Z�mW�y��.�����e��A���::�&#'��x�EL4�H,.�OK~=}��1�k]�B.�654��Y�MOOys��a���#�F�0v�b�ײ�^~���m�+D)��.n��<w��Ŭ�K&O��]�����6��}Q�����2���[����(�����lo� �@ �7�z?���#cSlG\B�a�>�a�H���)�X�y��o^VWV���`��i���+��<.���:>�j�̓[!�yp+�b� I)����7��Z��B�P�<o��>~��棛��T��ϗK�-��f��V�+ c����� ���S�&(q��Y�{��@ ��zݟ��&���%���$���Q�����1�����)�R��~��RRr +-�o��V�� [\�Q�MÚ��&~)̃��_���NOx��Sv��_Ǩi����>��_�}X�t���{�ߠ� hݟ��a^^^�F�7n�7���;vlϞ=ZZ]0���ioWKK�B!�%B��PYY��p��:�説�d��ݚ�~OCCCSS���rog���G���������ݻw����-l6{߾}666fffx���:h�����F8�aT�p��>���_���}�|�~������ooo�� SH$2�ń��\���\�`�����؞�ا����2�� B�q����?�8�m�le�i����.U����4g�������EN`�1@������pႴ�tgt?��HHHhs�9ȁ��;k֬͛7�����1c�tp-//��3g~3K=��ӧCCC;�>333""����r���ݻw���ug{������<:�>t�P��{ +- +-���q ���� 4������nSTT���l}���@2��aÆn-HW�q�@0���KII���.3���)==]RRrذa���aXLL���Y_�sjjj���������d������ӧ�����+))�������ݶ222�����þ~�������0d���*D�jjj���1300�79��.,,l������Puuuuu�������r:���B`MR(mmm�@'+��iii�p8LHH���^�x1����3GG���fQQQ6��f�ggg������x����^�z�pqqqpp��t'@�z{?Y��?Go��^�iFO�Z�wI��J��sZS[���}>7��~�lڬ�^v�8�� ��D"�V;n9��MFN�~�γ�8��>��s��3�8=�q����U^�����\���=l~9��t���ILLܵk����O�8���eii�q���f��������8t��9s�r��5x8DJJ*<<�͓�X�%K�P(�N���PXX���cGGǾ��ڣ��iǎO�>����r劁��1w�����/]���aؙ3g�\��Nk֬��H��K��������7#�Nj��<~�xO���f���0�x���|mm����Y��� �֭SWW/..���prr�铓��_�>u�Ԟ.LW�w�^�-/_�TTT����oڴ)//OLL��f9rdy\.����O�������`0<!%%�`0&N�x��)))�-LW�~X,ֵk�N�<)..���$%%���eaaA���Ν+�X\\<55���lذ!##����Ç�ܽ{�������Z�d �,55u�ʕS�N�����̞�����w��G�9r��^�X�n�֭[EEEO�8agg��ظs�N[[��ӧ;88L�6mҤI111{��x����^�;l�{�}�V�A9y��{;H��HOy���.$%��9q���_�)o��ZL�=q�m�5U +-J*]��#����� +-�ʳ�=�������_4��@c�m�Ǭc���]]]:�`�cccGGǃ.Z��s>4�TWWw��2x���~������x�U2�\YY��ӧ�)Y,�@�on����ŋ�̙ӻ_�.'$$$;;;>>^AA�ĉ�7o�����~���3g���\�bdd�f�?~��i�&11�-[��{������ڽ%�":S!)))������fffQQQ�7o1b�����Ǐ���N�<Y[[;nܸy��ijjr�\oo�[� +-��[g���WTT�}�6��{���[7q�Đ�*����MMM�@SS���4iLO�R��=*++���4hPAA��Y������=2��x���L�Q�F1�={�8;;Ö!�'���|ٲe{��i������z��[������Ǐ�N�qe�<VVV���---vvv>>>d2������SVVv͚5���jjjk������{���+W.X�`��� +-e]aaa�����9sV���t/��� t��/f�·=����<�-���{ԝ�i��d'"B�:������峧�����ךں�k�*�Ν ���bZM�� ��υ�����~�����?��|p��G��Ju(; ����1�� ����`�⃀C��:����t�رI�&EGGϘ1�J�n߾=--��ɩ=Y����(((��vb�����̿�����3"��@�[;���%&&�H$99����ɓ'��,77���.�/_����;�J�~�x���>|���PRR�2e +-���W`��W�^]�n��� +-�`�ҥW�\y��=��)?��ɻv�ڴi��տZ�����daa1mڴׯ_���C'WÒ��rss����u��NVȽ{��L�bnn��1c�ɓ'�<y�f͚��Lccc�������~aa���f\\������I���穯���҂�:�DEE���mٲ��a������0h� �C.\8{�l�l��ӛ<yr|||�����J��>}�ryy��~�-66���B[[���������Z�5Ǐ_�~����+**fee}�� ��0�;w���u\�=�������ׯ_�v�ZIII +-���� +-3���w��-�Nc]]���h))��G��� ����```�}M�%$ �V��C�+*05��ln�������!5���ً�j���~?4���V��,�m���"� �m���\�������2 �m���z���������Ug���/��o`��Z��x���4�k�8�߰X�Ǐ{{{����7������%::������ܿ���Ֆ-[/^�l��>�gϞ͟?��K��Ž{������:\�s�ܿ��{���CV����۷o��������OHH��Ç�_�N����e���������ɓ�ӧ���ر#!!�J�����ٳgѢE�o�������Y�bŞ={z�?�ׯ_+++ �����������1EEE���������}{'�N��G�����)?~<$$d���eee{�쉌��1ӝ����D[[[�L$a���f��#�Lniia�X�O�>u�T����hJJJ����펯_��5k�����%x����p8>|�����Ԅ�_�L~�@k�#��q,���***�O����f���qww��������ZZZ��Ʊ��P�'%%)))�=���m�6+��a2�t:]GGG^^>%%�������������L&߽{wҤIJJJ���L&�!��loo���R__?f̘hkkGGG_�ؖ��t��`4�_�>o!\3qژ�������7Ū+U������ק��X��3V���/p1��_�;��?99�����?�\�fM믦���͛7a?�����{emmmVV���uxxxMMM{����p�d~v�څ/���o�%�����H�^!�͛7���Ǐ711iii���|��)��eeeo�wm�#""���$..���w���7����������jeeS +-~����ٙN���x߽{7))��`�x�B��\��UVV�����#G�jkk:�p�B�rrr�M�t�B�Lfee%�hNYYY袠���������*,,TWW�葙��������ӧO��7���*F�ў>}��p$%%<M��>}?~��3gnܸ��rW�Z�v�Z +-������������L�r��!�碡��իWvvv�S���=2m��ӧ�ϟ�|�������O��ibbҞ�Rxxxfffdddk5���dkk{���u�֑��,^����@ Y���F�m۶����`�4Ϟ=�\�p������ � &&���� y��)qjooO�P�t:>b�_"���������wT/���nf� ��H���6'"h����m'Ooaaׁw>�J����1cF��C\\�����ŋ�^�js�n'���{��]DD����>Y[[_�|�3���%''�^�Z8�KJJ6mڴ~�z�4"��+V����ٸq#�J�Rzqt̺u렆6l�����o�~���$!!ݴ�pႼ��ܹs����O�.p���2����f&���˗����]o߾�1c� $$$���>}:n�8555�h*<t�B�L&������P(�h7s�Lkk�!C�|�����\CC����ڵk�.]�r�!!!�.]���o�]-�lܸq�ҥ���--->>>�7o������������upp,//wss������<x�ɓ'G��������z�jOO�Ç�344��d���!̠G�M***=z�������w�0��������_ZZz���Ç������<o�ر4����� z�葳�s^^^듴W�=���yZZ���&�6QSS����r��'O~���֭[�9s����544̝;v;��LJ���T�{�>�������������;�o\h��7�L�y8��&��j�*eee�s��YZZ�9��Ν;m�\��ə={6\& +-�������������߳g�=�|˖-+V��R�B8����j���4������~���HNN�8qbTT����we�hii���v'����BR[[C�@$ϝ;������p��9��NNN��ð{���ر������bcc�M��_�B����:th���˖-[�j����5�Ig*DJJ�H$B�ihh4h�@UU5((��Ç***��ݛ;w����իW���UUU,X`kk������{a�J&�Ys���w�� <XMMm�ĉ...��!C�,[�,$$��֖J��6CC��˗����۷����თ����[�1�zd������¢��! `Ŋ>�O� ??��f������;&###))���XTT�x���a�4))�����6���TGG��y:�̞GDD�J����/_�|Ȑ!��0�������Q}`4O�oMZZ�իW� .++ۺ�?�-�|z�>�"���O��:,,>��`�3���������?�0w�܋/^�r����C���� � ��k;v��������gdd,Y�����ĉVVV�)nJKK\\\�=jaa;FTUU�̙edd����[��@����l�ׯ_��Svtt455�l۶m�Ν,��8:;;{ذa���O�<ٱc����(88�իWs�νs�N��ޢ3"""�������ׯxK[OOJ���ڋ/{������ �IKK3��������� ������U���RTT���"0�]AA���544�WDii��iee�bŊ��{׀������/^��unn.����JsssRR��?��x{{Ϛ5�?�m���Džv����2�!!!�[x<^ǝ6������MMMaaa�� +-�H������&B���Q�t���|�����*_@�k��u���`��U������)))'N�pss�W\\����֭344�8q�@b##�6G�����ި���z��W��}�����aee5a�����999oooyy�����Ǐ�>}�kk�k1BNNFe��0���$%%e ���?r8�6� }bΜ9!!!ǎ�~�z��`ﶺ�:� 55��ؘ߬u����������7o�J�t\!,��Y�f=y������������7n�]�VQQ���H$�?���$&&& ��UUU�; ~��������<y�����������aÆ������A��M���t����(..������=p�@��=2�X���xK���������Q���HNN�7��g]all,))����������Wf��h�"������ zzz����311���,++�`ʝ>AX���>�;�?V������z\��$�n>�����ۅjj���ݼy���F�� &�ٳgÆ ���?}EEEVVV������zð��ܨ���ׯ+**�]�v˖-K�,QVV���[�f͊+�n�jff&��-���v�Z�lYLL�����\MM�������I���g0���mv��u���������������ǧO���ڄL&o߾}���<�ۇiii���l6���$ �j�@BB��ͯ_����vrr8p�����ZZZ�X�遼 +-�y�����oݺ���3{����ϟ?~�ԩaaa���P┕�ݺu+22�@"�����?������������[{ܻw�ԩS�7o622jhh���6l,�3|||N�<�dɒ��������[[�ѣGϞ=[YY��˗p�%����oggW^^�nݺ�/_��2���M�@����?w����ȑ#i4�͛7�����r���p����X�|�ѣGg̘љK@�����^��Uf����!0��0�I����o߾�d2>|(** +-�cccÖ.]*))�A<�~���~�;�q��G�AK }+�O����|��U//��s��[��lٲ��f��:88��nݺu�֭6O�ǿ�Q��� �IDATI��xG����5j���(4�TTTBBB���W�Z������'��|��fff��������{�ȑ)S��i&M��bn߾���}XYY�{��� ӧOwww��!�����χsG�-�����:t���s��c�X!!!����殮�t:]TTt]cǎ�b�8�U��b���������s�Noo�!C�\�rE��y��'''|#������������=\����ƆH$sg�����ٳg���Ai"))�{��3f������͘1�H$^�~���o���4MQQ�ԩS�o��������ߑ�<==�����7s���0��͛pV�Q�F�B+++���p8l6��fw�*��i�2���CFF�@N��eeep�۷o{zzVVVΟ??**�J�nذ���|]���t:=&&�ѯ��!�s����1����v�L]t�> A����ď�e��|\��D���M?9G0A��E�}�×*((�9sftt���v�]�ׯ���31fdd<xp߾}�ku۶mJJJm��8p@NN�~��� �Fz��%y���{��]�R^^^����3f��Ok|||"##<x�߯ZWWG&���o�������ܵ��{�}��'O��{<���FVVV��pڬ���F����0�=X(--UQQ�/ �a������}�q���`�6#���Չ���8��x<X�>Թ�]�GF���aX'+����/���y222lll֬Y#�\`v��|\��ϟϝ;w��Q2���r322��˫���l6�D"���!��ں����.\���\T%��E�}���x��]�]+��D]��N�"��6�� +-&�5���A�@��'g�ٕ������|o�����x�g����H$�ʦ���@ �������L&���|�ZB�a���666�O����c�={�08�$��&��70����j55���^�1������5���?���v�)��+q�;F�kn"| �5��~�y�Z���:��ZD�������h3�tF��t:�����D" �8����r�ܹ����g�n=��c��dܫ�@|��������.��gE���u��_X�_�tC�;VOOY��R]����ޏ�S��z�JVV��ܼ��A ���a���h\o���$�n�!�{HKK5B ѭ~ ��JAv}a{�������@ m�}�)�>���@ ����? ��@ ���w��V��-�{���]F�@ �@B+�~:[=]��^���~�@ D{�w{����8 ~�@ �>M����5���������Y@ ��p1�aX���=J��~/��@ ]��ZzGw�(�&�@ �w!!���_�[�Bhs�@ ѽ����@ D?G���������o�9{�>�@ ��tƿ�۴����o寻�D?�@ ��Z{��n +-�Mʻ�����g2�'뙜 �@!�ϧ�[~�������2���ں�ֈDLF�#))ٓ�B �*����!d�@<�B�o#IJRe����L��klb������$��@�g!!oB������f�A����r�$�<`<�@$`<�����+*i54@��@ �dz�&��i�����ٽpy<��A��?�x�?�������744�x��@ z���K��B ���p�.��a�/���'��5Ԕ�^e ��yy���{sss�{�������r^^^FF�@�����/_�ylEE���mMM ��ð�����R���.]������ +-UUU���ߕ���������������s�@��#��IMM=|�pKK����e߾}������t:�?aP\\��-jkk{4�=˷����2������ ]t�ޮ�6��xp����!D"���.!!C&��P\N"��+�ϛ7oJJJΟ?���s|����N�Z]]-))�w�^�@JJʙ3g�������ӦM7n\9�r?|���r�!>>��ݻ�N�"�=JLL\�f��Յ�q�ܹ����W�v>�Ǐ�������s�ζm�dee�3�= ����ϯ��2d���t뽅��rrrJJJpKKK��ϟ)���V}}�ׯ_�v +-����Ц�Zpp0�D����ւtWð�����RUUU|{SSSFF����СC ��Y�aX\\���I_�sjkk�����hkk��d�������#��<x�@EUWW���)++kkk�����h���*===��}��P[[[PP����ׇ79,r�����vb�UWW��֪��KHH���~�Z__����_?�naM�:Y�=���p8���/_��y ������ϟ�_���d�����d6��aÆq��mܸQDD$11111����FRR�`�ƍ����V�n��Uj�@�����[����0���{p�>{���2�@���ƀ��Tuu���?::zƌ���666�G�&<hjj����/V�X��\�tiSS���ӕ+W����F:��`0p3������J�����;w���ﵵ��;&""��7��Ʈ_��/���hjjڷo_\\����������̟��`,^�x�Ν�-�`���w�����@�@vv�ƍ��$i� ��������xQQQ��2�߬���a���gϞ�����hG��>}:������?�TSS+--3f^3o߾�y��I�z�,]B||<�y�����bee���[AA�����;u�n\x���������F[�|��M��{#++�������g��III����P��=2��X����3g�P����fIIɣG��7�F�-^�X 1�Jm����bmڴ)+++88�������k���ooo?q��ӧO��Uf�y��A�|�ԩS�N��={6�`ժU...����vttlllܺu�e�,--7m�4y�� &<{�,++k����f��b�(�O�-����b�\��IC���BY�d�?��(+��� w�}�QWPQY=HK]�J����䥥����۷o���TQQ���8p�����h3��ի9����3��������pYMM��Ç555���03���FFF˖-c0LII����0�����ӧ����_%��̜9�J�~;i�!,,,''�ѣG������;w��ux�ĉ�C��/\�`hh�b�>}��m�6111ggg|oAA��044�ޒt���w�ޝ={����&&&O�<ٱc�/��������SUUU�6mڴ9s�hhhp�\___�>j�f0 +- +- +-����999���ӧ%$$�<y"&&����������M�6���,]����϶��#G��:u*����AZZz�Сiii�V��=2�`������kff���p��77���X�G��ɾ~��v���۷�g����j�=<<���?*&&�u��+�籴�,,,liiY�jՅDEEW�^}��Y��+W=zTUU���&���9w��ܹs(**�������N�8ann�`0��x������+CN�Ј�~����/�\Z��2�C6�D22�72�' i�˿V�|H�I���w� 60�ѣG�=�{�.�����:99��QIIIOO�u����m���䔘�������\RRb``p�'O�|Wn��������뜜���x~w�O�>=�w��'%%�a��ů^��0,###444&&����t~6�}����K�*++�H�E��������۷�����ôi���KHHHII)**�;v������G͜9ޱ����\�~���Ǖ���T���9a�SSS�`ii��� +-��Ǐ���������nQQ� !!AQQq�ȑ=^���N�kjj�CDD����ѣG������D"���FLL���������gmmM$uuu�̙s��x�Q�F9::ZXX�j�~ +-�� &&v���1cƐ�d99�iӦ577WVV�����3���cǎ�����>}�����BNNN^^\mhh��>�[����y$%%ǎ{���$%%����ZZZ�̙��i���s�!C����M�<y͚5<�����&M��Wܽ~������Dw���}�$��GFF��k������<È������|��<�־@��ӧO7o��d�/_FFF����7o�<`���@II �������������(���)�&|����ٳ� ����[����8q��ߟN����������'O���O�8�?}ZZ����?~L�R�����ݭ���ݻ7hРO�>���۷o�r�8���pUCC�J�����N��˗-[�̜9��1---EEE�����<y��������&L�����ܺuK]]�� +-��t�B^�z�|�r�L$G���� �`�X�ݗD"����X,�#G��`!�:����XXX�d2544��F#�}�EEE���rrr��999��������QhhhKKK�M�zdZ�?�%##CYYY�q4;;;<<<$$��^�s�رɓ'O�2% �����/��=�RRR���i4Z�9i�2{&�Y__?h� YY�w��566���TVV666�H�������C79)))&� �h�4�^������`L�2����ZZZO�>�b�����{w�B_�ʝ�/������=_�V�(+(*�U��s?��(*ʩ(+�]0q��?w�����w&������ajj*�9����B�����զ�&���6*���'L�����HII9v옻��ȑ#9�����gϠ�///OIIY�re�g�p8D"1..N\\�ҥK����֭�����w uuu�O���E�����ͭ��������;"""%%����իW +-e�ҥ�����>@+8�F +- +-ڷo����1���6ә +-a2������������mmmخf�XEEE���O�>511QWW?q�D\\ܔ)Sz���{��hqqq���GBBbϞ=ӧOWTT�R�yyy�G�����~�������+((��KII�����A�}�ȴI^^ދ/ySUUu��i�0QQQ#F�2dH��FDDdggߺu���onn^�lى'V�^M&�=z�`���Å;�̞'##��k���u ��3g�����ٳ�@�Py�{���|vrr���WTT��"�$�?��^�oO���c�����-��@_����~*�����~*e����Ln^���d�qf�u�9s��N�~######*����C|cll�9sp'���:������t�������3�`�144�� ?Iii�m�֬Y��I$Ғ%K.^�hggG�RSRR�Tj�<V�^ 5�ܭ���[��,�b%$$�( ''7k�,��¿�����d2�L�URR����y���]������P�������>{�l��Ѫ����^�3�d2�P(����j�ҥ����������7o�x�b`` �� �v�چ z�<]�����ŋMMM�l�ŋw�ܩ������iӦ'N��l �{�������t:���?��;������ a�2�����U��VQ��ZWm���Z[[W[���U�P�ޥu�n�{�Q�= ٹ��q6�V���z>x< ����>���}���|�λl�9�|d����q�������� �Zm��\.߹s�Y����OIIY�h��ٳ}}}��4M���K��;w�-��Ǐg2�Hq�Y����.]�$���[�����ӓ�����:\�vm�̙�Sݻw��O�r���gϞx��6;�Q9f�o���}�Ϻ��h��y<�N�%���Y��V��Ò������t:��8�n�:Ò��L��5�0[�n���O7n�إK����c���������3fH�R����ޒ%KnܸѾ}��G���ݻL��lpc<T�]`��c����"ۖ8��?�\�n�.�Z����7~vܸq��a���?{�� ��B�O�~��w�ՄB�ʕ+.\ؽ{�:400�zGW�T�����1�=C.�]����nݺ#G�ԨQc̘1����ѣ�������~�z__�^�z�;v�ر��n�A�ި<��?y�͛7�ׯ��zyy�;w���u֬Y�7of��}}}��$Q(�V��L�ڵk];�\�e˖ѣG� *�S�����~���_����&�H.\��ʷn�bƐe���һw�3g΄���lٲ^�z��SBeV>.���r�={6jԨ ���a�ѣG˖-cG��r�����ݻw�m��^;�۷��ͭ��P�0v���7ve����q+e?v�������<��ɕz{���y�,�¶���J�|kիE�4]�~�&�R����9�zdffΛ7�_�~l�!���w��cΟ?���Q�Fmܸ���CIܺu�"e�M)))^^^�Ǐ_�ti�v���澾�ݺu���iԨх�-86�o���M��dddČ;��qʔ)�g��ݻ��Eu�Ё۸q�����'O~�嗆BCCׯ_���[�80::�nݺV8�r2�B�\n�:u�S;���kժ��4a�v#6l�믿d2�R�d�EWWW�\.���46$�B(�z��zh�~��;l����K�/���3 >2%�H$�^�v�ŋ q��'O!E^��T��ׯB�\��d�ʕ]�v5�]����O�2�ѣG}��)��&�i�����7���4m��[$??�֭[+��={�4mڴF���ਪ&�/[xi��(�~�A�7~���G\|������[�V���feI3�r�5mĮS��ƍ{zz^�t飏>bF�Պ�bC�a">>~�ĉu�ԙ8q"!d�ڵ +-�";;;##�m�wss�<y�#�L_ww�E�yxx�:ujٲe�-bX�իׄ �5k����&�:��5k�h��ƍ�$n�?��tE�<c81�u�cǎe˖�_��Ȟ�l�ہ�Ν;͛7g{����S�ڵkժU�v��^�jSAL��V��B!!$22�ĉ�ƍc�Ϟ=kҚKٹs���ý���Cf���J�P(d�%�j�:;;���mz +- +-"��.t������N�:Bڶm�q�ƴ�4�}�t�R��t���1�V�����S���e<����Ͻ��L.tُ�X,6�z266��l0���jѢ���������o\�Unذa&��&w�~���̱�-[J$���TǞ6�N��m��o�z�)rf>c�M�Yٹ���O�<�<؆"�4;'����#q0^�����w��i??�?���q�ƃ "����[qqq�u=z�k������aÆ��ݛ�F �t�D"Y�d ��ݬY�����03|�ڵ��_}��ȑ#O�:ŶY������.\�p���lxG������YYYٳ���!C�L�>=444 `ٲe�;w64����O�2eԨQ��ٳ'���ݻ2�����l����o�M��ϟ�ҥ��W�^]�bŸq�پ涖�PB��{ٲe[�n�W�^dd����[ױc�={������~����gϞ�;wBx<^TT�����ׯ�ܹ�={�Q|����~����> -((X�|yhh({�+V��r�;v����駟̾�mڴ ^�lو#�{��)v�a�^��EB��}��9�@ТE�������Ǐϛ7o�ĉ͛7�J��v�rww7����i|Cy���ȑ#�Νk|�%����qRRRq_��Uf��3g��|/4M�Lg����w�^�Z#�.��y���|����Ο~�i���r!�/��������&�ԭS+=#���-#3;.>����Z?�NVvn���:���ѣ�~�iɒ%���#F� +- +-j۶mAA;^!����&L2dH�F�~����@.����#�D"Q���5�R��������ڵ�q[TLL̒%K���9sL�;ֿ����yxx���A�������wFDDlڴi˖-_|�E�z:w�<u��������s���}�]�/iݺuTTԲe��/Z�����ڨQ��#Gv��]$���C��Һu��ӧ�����S����ؔ�*D�Vk�Z�wM�ڵW�X1{��?���A��W�6���m۶����8Ǎ7u�����/^�����"ئ�����$�DFF~���l(��o.^�x�ڵB�p������>��|��3g~��G���K�.e�o�Z��>�{��� �IDATlJS�N%��ܹӾ�~����w��0��ݻ�Yi۴i��wbNKK3߉���Z�F�1/%�Sde��0�����&$�ɜ0���'Nl߾��m�~�����̨�����H4jԨ������J�P���:u����x��/2��ʎ��_���*�/����g����㱰�싣R�._�[�~����7��x��-L�`��{�f���O�t��m����_}������$�n�������ۨ�����̘1�ԩSX�h�����:s�̱cǒ��RSSٻ�lޭ��˸q�ئ����=z��İ!Y����5j�YZ��f͚C��ڵ˸��T*5�z�x�Z�J��l���[�����}���4o�4������f��Y! +-���4`F*��]c������c|�����zxx�Q�^c2�����P��͕H$E��l�#GMQ�GƄ\.�i�̫���;�v+�:tذa�4Moܸ�Я�ŋ�W��7o�����<�x�bjjjvv�F���x<�M��ի�9C��=Cv^�oݸ��ۭ~A?):�� +-�)q���{xxx�������-S��0Lff����F�1�B�t[�TJQ�aH�"�^�aW.��t���v*J3������2d� M���Y�jM�l'W�(>2C�R������N�����ņ����d�=Cv\�W�B�RUq���wO��#�tw������2g��e�JKQ��n���&s�lS�(��F8�g#=�*Sff���sss### 7⡂x<;����!���Ojr����,����o��o�E�ޢ%�ɸ��������H2b������ww���0GMK����l�O��m'Z4�=��"U5z�@o_\]]����.��@��#������T�j��Xq���������DdY����Z�DE���J������"K�������J�J���'R����Bil�Fl�8�����Hiy>���VIm�4UZ[������0p��~�2m`��*��������)����ϒ����e���*�YGi�L~W%[(����ؘ�l�w���Z��pp����PnU��\iF��Z�*�����,�C�����oU3~?���C����@��"Ib?UP�-������̘����KTz9��b�����T�oO; f�bTE������U��T�L�-W*5z=MS�0�.]��H���8y�8UM����N5��+ڈ��w[����R�/]�tx﮴�j���� +-� +-�F���ľ���|�֛o�y�Uө����JT��AU��J���~��w����D"�5�B�H$�(����t:�F�R� +-E�gK��٥gߑc�5��g�������"^��'[t��?K��V��/�M�Li�ҳg����������P(�r�<�������z=��urr�p84Mܽ=�a�G�H?/��-<���@�`=w씯9U�U���� �T�m���}��e�ǾHZ���Y�X,�p8|>���B8��%�(��a�J�0�0��������Z����dz|;�j����ϟ?�~����|����� +-?���V��[�.�P�PL�>=$$����x�������5jܹs��o��ѣ{�b֬Y���>>>&�=q�ĝ;wBCC !*�J*�*^��jE"!D�Ѥ����G�Պ����t�TjX( +-y<���������sqq1���\WWW������r�T���\����ػ�ׯ�^��]�vl@�h4�f�rww7�-�J�B!EQ�����/^��.55U ���9kbr�Er��X.�����X�QJ�RH��_�s(�a>��0����t`7�r�5&�]B�j�<O��p8��Ϥy23wq��g����fgggdd������B������4h����0�=BIHHX�fM�V�[��\.����9s�����x��킂��g�2C�{��={>���%qrr�0aB�:u��®]�6j�(����7�|BHrrrdd�a��<k֬�ӧ_�xѰpϞ=M�41���_~�������_�������#�\�vm����f�2�^�wZ���ӧyyy�7vss+��g�<==kԨa�D$խ[7??�=�!"����["���ƍ�|��q�z �����0LÆ ���&>>��6lHQ�B��s�D"iڴ��3�0����۴ic�gN �T*�<y"��4h�6 ����t:�-Ԯ]���7Y������m��[>2&�R�G��|~�F�L�U +-�!�RRR�;+RSS���jժe\?lM +-��z��B̬�J��ju:]�ڵϞ=[�^���������ɉ'*�J�ןF�1bDDDĤI��\��ӧO�>M�4���/r���&L��㱲����[l��[i����T*U�T�����T*�X,V( �ԢLO%�����P(�z=!D�V�t:�����T*�܅���^��U�Vhh�}�222�.]���R���L�W��iӦ:t����/f&%%���E��I�>}6lX��;F���� A�ȑ#�>}*�H�իw��I///��K�.^�j�*�\n��.���._��p���Ϗ���J�f~�������8q��FoEbo�;v��Ņ��nڴ��L��d�z��={���� !����o�6mb���ݻ7b���<o���S�L1n��iz����-��c*?�Z�e˖%K���\�e˖�������z�2y�X,�y�\.=zt@@@bbbDD��j��ի���{�WI�a9%WH\\�����S�H��h~��{���?6������߿j�*��.�ݻwe���#c���7.Z�H"����z��-_��~���E�!�/߾}{qg�{���9s�4���͛7?�����{o�ʕļʬ|����Y�ؿ�駟~���Y�{`���S�N�/5jTAA��3�9aΝ;w������������o{��Y�QY*7�/ch�sY:�9")�Eh5j��\���t:�a�juv�z�XZ�q���z=;����6�1�ժ��EPPФI�!��틋����nѢ�0���[�`�֭[ ߹�������ׯY�&666==��ˋ�����ߺukҤIB��]�x�!c999;v�=zt``�a�X,����߿?�p�ڵG��1c!���sӦMw��]�t����IܯT*y<�V�5,�h4 +-���k��5p����(������ӧO{yy-^���/�طo���ta{��Y�f�o��f|sfӦMM�4�h4������H$���/ �������7n�غGb 4M߿������2��o��4i҅��too�ӧO���2�o��(*&&���ɒ%999�ڵ�ݻw``�^����_�N�jhó#%T�R�=z�;����t��Q�[b�ڵ4M�/��t�ƍkypp�~��G��r��k��>2�bcc7ou�ְ�0����o��믿!ŝ!�J=+v����GZ�bbb +-���ʬ|]�v����j��F�Z�b��3f�ҥK���G�1o�<��#G�+�[���?�ׯ_�ڵ�B�̙3w���^ ���o�GρsM��x>���Z-�0lX���t:�@ � +-���ɡ\�Cx<�^/��Q}x<EQ���(.Urr�ƍ�nݺp�B�V{�ܹ���'N̛7/88ذ��߳gϰ��Q�Fϝ;755uݺu3g�:t�ܹs�z�.]����-ZT�^�A�]�p�w��Ɨ�����J5t�����߹sg��{+ +-BȜ9s�̙c��[M��Ν��x����:u2Df�?NII�ر��� qqqo�����SBBBbbb����{��=�w�}���W�aT�F�ټy��ѣk֬I<x�M�nݺզM�"z��̙3?���]�/�H$쿥���Ν;��a_ճgO��a�ʕ+�?���nӦ �_������/��A���g�.]N�8����&��\����F�Z�reDD�O����lB���gHHH|||``�S�|||���*�h,�� +-9t�T*���/��2=z�`_b���۷/''��/��(��������qqq�v�ڲe��=ml>2&�4ir��a6������>�?~vv���Wqg���� +-oo�<y"��v��m�{��V����ť}��cǎ9r�D" +-�~~~l!�Z��S�v��i|�888�ȑ#...,ظq���6�� �����CJjd�l����[ޭطJ8d�F����$�LF�tvvv����bb�)++K��egg����4���Ǧ�����%&&f�֭...�֭2dȨQ��j��}�BBB�3kw��}�ȑ#G��l�2>>~ҤIJ�rƌ���f�M�63f�HJJ*r/�ڻw�̙3U*Utt�رcSSS �r8���_DEE�\�����9z��K�����.]��{�yzz.[�����!!!�׀EDGG�7���)//o <0<5��'N�X7oޜ0a��z���q��͝;w�С;w�4i� +�����������&�Ԯ][,?}��ȕ_�x1q�Ğ={�3�� ���o�����C��oߞ�{ѢEcǎ�u���͛###�;���qR��;wj֬���[�����߱c��ɓ��^������j�j���_~�����*�ҥK=z�pqq����~c�������g�/_��[�nm۶�v�-��� ����3�D᳢N�:����'؇W�\���i]q[(�2+�J�JOO +- +-����v�ZAA�\.OOO/((��d{���ر���Ozz�R����}��ɓ'O���ؗ�3����ˁ<x���?W��XUy�������d#Uf��i5z�^�׳�>lJ�&�:�@�n��>W������R ���h��0`РA��ɿ�������/۷o��h�M���w߱ �������W�����ܹsU*ըQ�bccCBB�w��~/Z���_5�q !͛7_�p!�N�u��ٳg:t͚5�[ +-<X�d�̙3����j�I�����3g�?==]�P8p�M�6ׯ_�2eʗ_~���Ծ}{�U��|��y�-Z��j�;֬Y3BHJJ��˗��F����\�+W�b����/��?����.���B=�(�������(�fZZڤI����BCC�4�ݻ�ʕ+2�����B���?6<���r�֭�-[Brrr6l���?|���<z��V�Z�:� +-x��ə3g.\�������3c�����0C>FPPPBB!D�V���>|�M�6�j՚?��cǺt�2y�d�K+�B�<yҾ}��~���������|��ȑ# �������������|�����6l��c�|dJv��Ű�0����3�X�g�B�>|��?�8z�h>�����>{���%Tf�}�����ٿ���k��m۶�s��IB��ի�����+B�H$�s�!$::�رc��1c��¼�����C�P��ʹ[KS�2���WvJ��0ÎS����j5��N(��~2Qh�����M�k^y�R��ؖ~����j����<�cǎ:�7N*��������>>>;v�(jΜ9�N�:��ޣG�5jT�Ν������SSS�����7oJ$�����#G&''תU�I�&W�\�D���3f̨[�nPP�S��;#Tܼys̘14M����������T*Ubb"!D�P�ڵ�F�Æ ��d���{����xÆ ���$�TZ��˗/?���cDz4�|��a�V�X1~�x'''6�7�1r���l״iSBHff�}��l��qz����LV��R�W�����իײe�"##Mn�'%%�T*�R�R�Ν;ׯ_?���ׯw�֍�������q�رv�����MmMzz��Ç�>}�V��F&�EGGϝ;�p�ܽ{��}�6j��ɓ'm۶�U�ք �lٲv�Z�^�v�����9:�-+\!4M?}�����&Lظqcjj�W_}���l�x!�w��ӧO�Oĉ'<<<�x�J=�G�];~���ի�yg��"� +-���~�����[�nխ[���Ó&M*|w��ʬ|m۶�}��L&c���������)�z}�N�._�<u�T�����Q�F���^�z͟??00����;v쨬�W:�����(�ƊS��<�� /�W�(@�"���å(NV���/�S<��]ʻ E/s8OS9�Ry�*M������'O~�������]�v�;w�{���[��С�ҥK�n�:|�p�T:o7n���v�С{���}�]tt��s�Z�n}�ԩ���A��C�B�|�?��s��]vG�o"ooo�!����Ç�W��L&�8q�رc���v�+W����J�Rë4h0k֬����s�j�j�ҥ��ӦMcƐ/[ 233�����\�,�.]�̟?��ի��ΡC����_�FY��e�a��Z�JeX���S上g���AAAgϞ]�|9;<��g�}��*a���>}zÆ �k�'NZ|�B������N�: 2�O>�]������""""""�r�� � v��A������4M� K����n�z����5kN�0���իW@@��͛�m����ׯ_��ÇO�8���5[Vd�������;�'O&�4j�hȐ!��ц�N�P�;wn��م�v�ʕ��z��:ð�)Nvv��9s��}v�'�S�b��������?<q�DӦM[�nmh�2VBeV>vRθ���C�6j�Ȥ��0<X�r%�w������۷7o�̞`{��qww/|Ñp(K����Zh�/��F��h4El<��!��� +-F(Ru�x���5��.=\��C���aG��p8\.W�1w<�����G�J$�ӧO�k���ͭe˖ +- +-:~�x�Νk������ȑ#]�t =z4�@���kr��������ҥ�߳gO�����/]�t�� v5OO�����k߾��~��'�ԭ[�k;vLHH�������:v�X�f��Ǐ7o{�nBH���7n�ؤI�{oڴ)99900p۶m۶m����裏�z뭊�%KJJ���<y�"""���~~~QQQ�jҤ�ٳg �-866����aj4����"�)O�8�u�ք����zƌ���c��(�����æM����=zt����4i�m۶�/nذ�W�^�w�.��-�H$�]�������U��a���g����5k��ݻ7??_�P�������d2�\nw�YI� +-iذ��E5k�|��V�e�O�?NӴ�0,�Z}��y���>2ER*�ӦM�j����!���3�X�g;�ell�~Xr1L*�܇c)���&Y�4M�|�& �m۶ +-�bǎ͛7�Y�&����ʲrI��%���H�hq6s\�\ly6UBE1bgg�X����������������jkĿ� �q9��N�:������>>>���"��Y"1�j�D���p�������*��;v�?�f͚QQQE�i���ŋ����СC����aW�\iѢ��=z�^��7n٠A�������&M�ԩS'22��7eM�0��;�Nj����ކ����k%$$�T*6)vʔ)aaaO�<a{�^�z533sРAS�La_R9M�����ȑ#���-Zd�pַo�}��=z����x�3����ι�>�����tEF'��'����5k�$U�6ٻ����7o�j�����V��r�+V�P(�/_��U�Z����3<d���&9?���;`����_#G�d'��xl~�B��Dv4 k ҩS��Ǐ���˗M�65�t/_�$����B2224 {z�#|d +-+((�6mZll�ʕ+�ӺJ8CL>J%��Z��H$W�\1g��ʬr�YH�/�_�~�.]ػaaa 6��� +-S�~���Y���0�^�;wWW??�����8�Z�V�TB�P���-e>Qj��j�a�J��j�4MS���������s�uk˖->>>���:u�lڴ�o�6l��ի�֭KQTBB7�=z���Q�F)�+W��������?���?��� +-��m�N�:ݷo_v�ݻw�������_�<yr�����YYYlDi߾}����R�e�ƌS9�Xu��e��Μ9sȐ!ǏgG2m۶�����y�F�e�|���)�ɲ���qV�RQ5|��)S�4iҤV�Z�-���,�mۀ��O�6m�С�ӧ�����������˗6l���`#��g�v�����K�.��믟}�Y�ڵoݺE�S����bbb����)S��l�26��� �IDAT77w����=��۷/Z�h�Ν��4##�8>3����s�����Bx<^߾}Ϝ9r�̙>}���@�%TH�n�V�X�dɒA��|�2::�8����/|����G����|dL���}���ϟ�8q�g�ث�5j���w�ܻwo�С,�֭�a#������1��˗�} W�Un���&�0c�gee�ڵK�R<xP ��SժU+�a,�HJ��!��]�ơo��֣؇��B��i��`�ڄ�ׅB!�Syk�Z�^��[M���aK��͘1���+��_�ζ!��sww_�x�̙3'O��}��˗/�;�s� Z�x�{�&O�<}�t63A"�<z��ҥK���|�����o߾��ٳ����{����r8��{�};##c�]���wo�&M�s� !����V�ںu��իCBBAzz���GBB�J$���M^�~���X��˨M�6}�Ѽy�ڶm�������駟�}�]�:;vd�bN�6�J +-im]�v�5k֬Y��rydd�y�J}I۶m���p�B��앤��[�ƍǎ%�رe��� /lذa۶m�L����'fΜ���o[��)**�a��۷�Sl���oܸ�펢V�5��8�)))ō��iӦ�>��p+`�ĉ�}�٪U�BBB~��W��ŔP!�d۶m�f��֭�H$�ꫯa�/���~����Ο?��yB���� V�[m<�E�gE�C�Y�>2�w�IIL�3MIIa�6۵k�ҥK322���s��!''�q�ƥ��Μ9S�T���I��[��@Q�����3�I������xm^�g{�5 +-��߳�[ؼ��͛6�={�����|v�{�G�4ۙ��x�����8|�'Ç 1s�쵄D"���k߾=M�;v\�`�!�P�T^^^r�\�V�7^����>v�ؾ}�� qqq���KbbbHH�?�p��=��Ɗӯ_�w�y������}�}{ӦM'N��;w.;��-[�lْ����o,X�@"�<�<22�k"���ݻ�f͚0aBFFFPP�Z�>r�Ȟ={�糬+V�ؿ����J�R>�oG���j�J�e���q�ƴiӎ=jҼ�Nj���n�=;e2�0&RPP`�i���T�fM�d&''���Ӿz�Y!,�T*�����Q�#c��g�\.��k�Rݻw���#F�0�\0�z�jC���ϟ/_�|��|>_��w�ܹs�������̞|>_(:;;��۷���엞f���L�J�������<+V��ʭJ�Q�_&��ܹ���SW._NOO+��9;�!��ė�ig��fM��7��ԱӇ�s)ח�^��p8fF�Ʋ���jufff@@�{D� �L�����r +-�0��Ω��lG������4h�L�����߿�/��ҩS��*�#�����a��R�#�0T*UVV�����gggÿK6��h�4���e!��Yb�/g��6�3f�i�-�E"���M���g����j���Q �5j��F�7*0ie��`J`�9�P��Sj+�@ 0{b�̐��pS�W����^�z���|����8>�o�j��R�#�0D"Qq3�yz�ֶXm�~�Vb�2*���b�����F�*B����o�������Eww��mۖ�R +-���ʁ��~�h�>�*86WW���Ȫ.��@5BYl�.�r���f�f����d�q?U��Ǯ������a,2_/������6���&ۣm�P�2� ��������FC>�,U!6RL)F�l�p������X:����A#?8,���/� ����X����4�t������d�q<��_Ul�0����`��9���vTd;**����T-�!<��}Ƥ�Yj������P��?�����aYe�.;�����!������������J��x\a�>д���j,�^��F)��ҴZG�:/�������0!%ElB�xEQ��T�W~a��(���(�� �����P�R�|�<E�D�m��B(B y�%���`�J���\����2�m\���@ J��gʘ��������Y�9A?�����m*e�.�Jn�G�����`����f^��a������ ����_[�Jŀb�IЏ3�����1f���}VN i'Q5����@���0������`U������_���,=����* C�2�������#�P�������2+ߢ�JE��3�������.�%SƏi���OF�]�a���(�W�^!D�T&'�4,w�H|��_&&h�j�B�����ٜ�(��r �������H9�0�$n���<{�d�͍&'��ߠ��cG��y��a�Q��X^x���ޘ�P���&�iX�f��y�~�=m�������&��2��������z����[S�<�ע����B�=}�y㟛6\8{���ԭԵG����Z���#�~������9|�M������Q�'�����|��=N���^g�v�|2������e^Q�B?�����wo����*r�Ԕ���$�ç�>~x�a^�L�˄��E���������w�6�Ϗ�,.�ebX���:�C)�ˍWi�(�a����a���!)�I�c�e�\a��؇�i�&/���VkX��j�2����R�w$Z�������©=���]/���t�����I�B��H�v�|��D�����V�NzZ*�p�����������,�߾q������!������e�;r�nP��!CKx�����2��������Uj��?��ѬEK�,���ϭ���j��;�ߨi����Q�T̡�ׯ��<.��G�/�>E�4�$��ݨ��<ޮm�������u�뻸��o�H�����A��'�������z=!$3#]*� i؈}��Y����N�d&%&nZ����{��֮Nx�2}��;�n�ƛ�{�ڱ���q[i�h��=�ϊu��=}�~���~i rr5~����6oa��pE5jڜ�P��P����uss���%�����\�Z�Ѩ�ܸ��ͷss�uz��{4�����d����۶Bn]����c��'�4m�*�[w�^��ǹ��֫S�^nn���22���盵hI�p�LJRRZJ�RQ�w���wo��}���� {y��BQ�P���W��^&&��cyr�K'���{�C�4�ȱ8ZO�?}Ҹy˒W�|�� ����x�����[�>z$7;K��8��ȩrJ�����c�����]8{�~b�����c7h���cXa��/��~�n�Z�n֢�M[;�ߥ^P�M[[�j��ɣؘCRSS�=}s�@rRR��`B�R�HIJNIJ~�����=y�v{E��ٓ�����i��o����IIJ*�#ѿ�.�����[�)y���ޏ�{���7�E<~p?�vin��c����w�r� +-����V�0l�!! C^�G�V��\��iͪ�Ą��'g|������}����z&���Wm��>����g����t�V���j����%?Ϋ��7o�����Om߶eÚ?������u�)gu���ݛW.��1��/��]]�zL9s<�U�p�B!vv&�89;��I_[�:V$����#�RR0gf�עUkBȐOF|�Q'�S���^�� i�0���� ETJœG�{vlg�$%�dg͙�5�p�W���o۸�έ����&M7���ah��OG�X�$-5�����W/]hڸ��:w�n�1۾�G����<s�c�H��)?O*qqI|�Q�6n��i�*�V���ry������B�җ/����4'G��O3t�T���X�����Q�Y0�����+U�gOw��Aq���祧�>��_��o����ˋ]������!��Q*�r��ҵG��Dr����{wn���w�F* +- +-��G��e��{yy�S1� !��a��:���{*��a㦱w�9�.߸��� �W?�r�ܙ�o��r�^>>��jm^�\�$~��NUu����`A����K?/��V�7��?λy���!ÆQ��$�������a��h��{�#�����*��0 0p��i���j����cҘ��]��onN�R�d�j�F�'��ege9����L� �����?�z��=��i����)2��͈w\��ؿߍ�R*�"E������T4��B +- +-���Xq�߽��4�5�G�P���-Ǐvw��S矝۹<�0m��5n<aҔ�����~�`ˆu��d���d��-Y�>l�(4����%�H������K�ݾ�u��G���J�6���t1;puw7~(r�0>������"<R�@�쩓����������� !�?է��+����*���5!�ahㆍ7kъ}�Z����0l'�ISB�a�����`����99��?-5�浫�3�ڣJmK���{[+�����B�K��r� �$|�9���6��X�J�J|�^P}�/��#����%<����xy��z}nn���;�Ϸ�ޭ�a�~�F_���W�P_O�������if����R�O E �2�B\\_e�ש����r�' +-������"P����ZES�e�8�i�/�>�����P�����J�ϊ��(�����������aX�)�����B1��.���3 +-�����0��ߒ2��@����`����|���������X`�.��stj��:��'d8f�������6��T|�EG���R����@�qJ��A� � +-������>s��K��h�W���)y�������� e��[�X;���-U �#�����E����N����;�+k�V��҇l�}����{d��|�!���;���`�,0~�U�eCÿC�������06��o�������ܘ2��S�*9��wp5���P}�A�X��-uU��Wy������i�|�[<�F���`��#���8d8�����%���_*D�����`�(B8[�����Gg��~y�T���jTܦ�8j�~ٙ^��Bg��X�Z%�����k�Xܟ��L&� +-�x<��� UB��ϓ�I$�AU]����������� +-��뷵���<����������1�2�eF��E�L���Re[�Z&�P*� ����PQEq��}�?��+q+JE�P �vY�� ���iU�����*�as�|���Z���GN�����K����JV�y�0�'�����})C{��"C��_``M�����kx��o#p'�����Jl(������+���nF#�B��T�,S+q�����m�2����R[����*�#��6�б�*�^�������W��N,v�]��X�<�r�|��������a���h�����0S9��,�9��E[�)���������(�p۹����b������������)@�����&8�����������aً$�����������N���������������d �K��k[A�m���(�yb�����`��r��������o������h~?E����Y���_�����vz�� �����p��e�ی��������c����(AĎ� +-����Pe�y�O���������S��Ec|�����å����C�³vhg���6J��B�����[���[�ʾ3P.vQ��G�������ͳb~Y�E�h��L������`��~�"OQ��z˧�[߫Ok?E! +-E�X\�|������c�<���?��4��QE�����v�a,��Ůb������@4_Yvᑚ�j�^������Ά����������"(����|JVсt0�?����Tc��c �v��o5YV�?(��&�����F�y>�E�����;���P�(���������=���� +-��J��l<��<y����*�����L��,2ήh�ۊ��+�j�2� ����U���(� +-�����d�7�,p�j��y��/ �(+����1c�ޒ!�������7 ���]L���������d�]��:��Sޭ�bVBHE����`S�����ZᕜŮί��[����2��o�&x��i�O��/�� װ˧����ο��������y�h�/$�����!<���������[,�]vN��v�ϸ�d�%a|.'�KO p�_K�ȥ!�n�\���ʜ|V��$���*�2��������@a&y>��?���HO3a�ڃ��q{���1��S����� K���K� s��8A����-�=.o�����P�Yx��m�r-��LxL��.�K?�_QR~I{�����H��D/t2N<��c�ޯ.�Et��J�C�9����@�qH���r�ǜ{����[���3�iSK?�(S^��fň��n�"n ��}���N�� PC��<���D%�E��aT�c���pDFw;� +-�� +-/�N�/��M�/<#��Y@~ !��e��_��w����+XH���C�����8K���,> '���cN:��v*�����Zt�_$���ˉe�.������"q?_ ��J�[�C7t���p�Ya}O} �)�S��@�E3�����t|A�N������!�)W���2p�b7�JQ�x^K7b��"d�u~�;#��y�P�i��KĎ�i)�+ᅣ��"�"Y +-j���m�9WZ���vU����,�W���T_�b7WW�g�7 i_��<�qM��=N:��(�'�9xQW��I��p��3��p9�� �s/���d|���D��y�^W�ԯ��g�*|�Y�Mx���`aB�4��p8��p�"6R�!<.��d�ieG3D�#B�Y�8^�RwSx�9��)��w�m�T>_��p#DŮ`�B��E��������8�V_ߠ��xBH�<��-)��"���!D�,Cfa�<�_7DR�@���rU&扼�Z'�ډ�����>�y�/�wQ6��)u�D�SZ��C������*W-�%Q�w��4I�KRd"O�^ �p��b����JԵ%J�N.�y&Y.��7�F���)����a���X"�e(�4M��z���r��pR{9i��J2�BO'M�\��)1��S��H�)R����9g+�N<}�\��0�8�i��S��wV$Ȝ�*�C������.�y:i�Ƀ]�H]����,���a8��kD\���:�M�8�%Q&���z��9�符�.��sU$�ę�< _���84��x;��U<��U�k���u|���H ��8�@����P%��i������q╡���9<B��@/Ӽz��H��B�%���"����&�bu�BH�uV�_��b�"��Iԩr!!�[��R�z։O+�BH�D�,B\���v�&��ix�� +-��F�������J!!�O�J��!a��bQ_�:M.$��k2v!�b�E��I/B<E�ի�6��N� M�ݙ�/�r�;vW�>_�-��]��|5����Q +-L��E��ix�w�N�~u��"��4|B��@���B�|Z�}�;�v܄�<5��Ќ߈����� +-������(5X/К�U���ԯ�i�k����|�4��s��� !�О[�>����&U�m1�����mq?����U�q�|��eav�Q�-�־8C2�������(�^�V�����(�׆�A3-������(�4��F�hJfs7(������+��W����l�p�f�?��jf�k�bWa��X�����ݯ�z�[���ůXy���@q��6?-!1�uX�V����@����~Ϋl6�����G)��;����T�R����inq�Vm���8��{�x�����~��6����B4z�����������!�ZG���#������������l^ y>��z���.aE}e�+9f��ݙ��r��*�O��������!��`b}%���uwmF-:p�������`W�0�P������o�g�%�q�X�����A����l�^�o�m�����Ƙ��OQ���7ڳߒ� T&���� 2���ʝ�n���b�U;=3!@����&��|�ן(���&��&������4��2S�8�A����� �[>,�mv`,R�9�A���@ 0o!���o��̌�m�������8����(�,Gh[��ڗ*�bA�����%�J~�T��7�~����(E�����n��� �IDAT9�GQ\.���ߢ�����~V��A�iZ��{�����j���~�"š����!����Rx��R��ǡ�j������R�~>�c����C�%�"[�����1���ϵhH���!����������_���ª|ܛ�@x[��Ղ�����5U����б������A���c &����������6�#-�������c����î��Wn����6�&��Y�������!�����������`q�l���0��������j�/y�� �t���������~����������~�&�����Pɬ�ޟ������?�-u����f��:����ۄ������Q�u���j�i��Z���5�:@���m� +-�i�ñ�-������U�Bq��G����))��۷nJ�R�BOO��M�=���g�gX���+ +-��,����m܄��^��_&���� +-�U�����<���\�}(�ɒt���y�Q]o���YiW��[�ܻ��`�1��K�$��H���!$��B!��@ �f:SB�� �.[�e[�����}?�N�3;��]���K3wn�]}xι瞛��^V^NDׯ�vvQ��h�����j��_-�8e��Ъ������oW��ZI$���C��Q,ֽq��Hk뀁Չu��m���@������*+��D?����@���{��7^����{ͷ�>����>��Ԓ����[��u��P8�-����y�uϞꚚ̟y����M�Uذn�sO>1y�i�� ���Z��+/WTV�A��7^?�o5����������m흝��}�.�W�Z�0jԲ/>oݽ��E�Ѵ���7��y�?[V^QPP@D�eeE�%;�����SDTV^����L�6��#����������W���i�� ��=�����5������d-�f���7�v��ŗ.^|��W�{���U��pݵ�Eyy�ig�ED_�X~��w]�_p�A�=���AٚX�s��#k���o���ҥ6��u���˅����ݻ_��ұ'�4f�"jܲ���F}4f��Ï<��{��%����+ʆ�kf}̄IS�j����@ 0q�T}�x,�H$N�{�n (��+/<_?��9�1��"����^�gK���ի��?��8"\T�|)}����������@@.-+W�w��шQ� +-CjI04WV��[�0�a��'�t�y�_����oo��ȣfgkn�K��(�����7`������)��()-So�\����N�D4`�`[�X�;���"p6o�PUS +-���Ύ�?�ള�a�p���N"ڸn]�� #G�lqW�γ��c��JJKKJKm�EZ��p(�%�a������a$&�dC����"�[o����]/� +-����˿���H�t�w�b1"R����+/�t�y��#�����7_��|ٗ���'��Ms��͛�����.���[�����YYUED��{V�XADUU #G��E�\�������x���j�5�V�OU�/[VUU������m�-;w�?��s.�nsSSqIIAA!W��?%"9(�����x"��f�:��o�����~��*�?m�h�'�?[t��S_��k~��n�Y69�9�w�y��O=ID��Éh����ʟ^�ղ/���w��9��X>�̽n����G�\��G�����sOS�D��y/1r�m��@@�U�uE��[�l߶�_����7~���vv.�lѓ�=zޅ1�֬Z9�̳��a��U�lKYY�/�����o]�٢ʪ�x,ƈ��n�DZw��L�t����$�����W畗W�;./����������۶���v�� ?���;���ş-�旿H���?���>���c��;ֽh�'��_,]2㈙���mc��lͪ׃P**�F�}��Y�W~��P#m��P�=�?���榦���V���_��[�lV�ں~'~s��ѣ�NB�peU��A��p�����;���r���Z���qkm]?�T�OD���u��wvv67�'}s�b�\U]SSS;z츁��lܰ>�������?ٌ�����z�����~{�-R 0a��[n���.����z�C���++/��/~�����K~b���y/�:�e����}��������VPP[$��k�z�̊��U+V�B�����ի���Ǝ�x����^}�`0x��Y�xlѧ���K�Θ���ܬ&�!�X,����F/��������%�F���������*-Kn�u��{|������7�i۶-�6�9�~��=���_:jα�۷5�����&1��i��Mg��������-d-�'uvv�s�]�ǎ�յוWT��S��v�56o^�+ZRRJD�ǎ=v���%��ںyo���p�7�1����>���mAAa���+ҿ���������FKJKO��\&I˿����c������<��_���C���9���;hN2�iɢ�K-�Ã��{�YD�fժY���۪�wC�z�g�>�d����ֿ���o�� +-cl��?���?���|�G���Nj��?r���?��K (+�8�#ǎ�����������f[��\a�r��V��kv67�t����%� +-���Dt�mw���/x����/�\Sk�?q���9��|7���, ��hgG(\���pEᜫ;��>�X<�H$BZB$'m��?��/�)s��b�XPNn����b��ߪ(��� k�2&Od�vX]vN�����B +-��[�e3��)��w�h��,�Hk��`#i�D"D�9���{5�1s|&I)�3(m���5�F�����{��H��s�������8>�|z�j��W_y91�~y�u�:+�/��K�(N�oZ���1y*>+�������f[s�17m���V�i�D"1lx����H�[�6��ՙW::ڷo�V_?L +-�:�,�����|Ϲ��Ϭn ������ϒP�co.`k��~��M�~'���⃜��.�Ơ������(j|?Nc�����`߆S����������9�i_�Ӂ��������)��߿�l6�0�����}F�|@���������pE�T�C�������W������W������v����j�%�ؕͩ�*���sk��XtpoO��a�Bp��j����������La�$�����: F���'�Hbף;n��Y� x��W=�?��������É#�������}�l���\]��y?}5Χ�g�'`��ޞ������)c�����Tv�ʎȰ1�q>�A0�h��������}�~�����@D�t?�������8R����<�)�G�����zgR��{�~@��/l`��������pr9�+�8խQ���Їaw������d�Đ���������������@������,"�>�)�>�?�����������}%�g��}pJ�������� +-8��W}�`o�A������a8��&�Iž,���w������0M�s[��>!�Ӕ�{��ܛg�j�{������#�v���ތ�����������}��ox��^G���]�����2N2'�T�:'�cA&�����������7I����7�|��_"�������wa�����{�r�r�&z\�����)�����@���I�91rQh0��<�\�h�n�z,����� +-�87T'���_���/�;���U?��Ow�~����.���=g�5)'�χ����H$�O�n}���Oc��Oc��,_V/Jk��������p�dJ�{FƦ<����iӦ���>��>XئegsG{G�=���]֯��ҋ�@@Q�I�&1k���+57�?`��/}��Wg͞m./���uϞ�{t��\�w�9k�MΡ�����'�y����G_��$gyvL#1�������@�a�e����^HϮ��B��o��հa����|�����j���U+�>����nmmݳt��c�u�̑G8{��w���w�5��1Aa(4fܸ����_\�9ǝp�UWwtt�>���۶5�y��H$֬Z��F�SPXh{�y㆝�� #G����������~uDԲ�eG����Foټ��������,z�+V,�j�)sOݹ�y�����8h���#G��&�cݱ��GZ[����"�hkߴi#���ڊ*��%�S�_�b�����y�3��OI ��Ѐ,�7^�gwQQq0TK�Dk���*��,�o����>��ܬ$�y���G��8�3/��{�����k�����{?��b�`Pmuڙgv�"�F��PH-L$�@��>x����x\-���E�E>G����������ZZ +-�,Zt��ߑ$�7�x��O>����A���9�_P^Q�������W��<��GǍ�0fܸ�ߝ���^QY������q�����Ԫ=�^���Q�6n���S������M��������hދ��j�UPX�䳅g}�|I�v45����DTV^����L�>c�MM�_~��!C��475�?~���������������� �0�����|,�L��8/KYY�eW\AD�[�^������������֛n\��g������VR_?���~����YG�~�g���<����;<��S����G}�z[?l������o��wg�{ީ������?��?���{� �7�<�^z������n���?x�=�$9���9�'�U�lۺu��_r�>x߽�W~=z�8�Q"��p��ߘ{��a���¢O>>j��Q<����8r����7~Ƒ���_?�dѢ��=��EY�v����y��g�N�>c�Q�v���C��4)''�ظv��^r�����+W�5j�/�7�}̱��H$��e�S�=��@ �f���~��g���R�#w� +-� +-������y�q&��A��6^��? 1�j��K.�aQQ�u7��i�C���g��N��K���Cj�1cǝ�w���8����}>LDW�����{5^��K��S�n�?������/�^��&O>����ȣ��}̜;n���>7(���`A�u2_��ʼ�H���k���jٗ�~J=e��M���/(,�$i����7n��h����5h�P"<d�&�����^�uw���S�5�jw,�F+*+��i�ƍU55�pQ[k�����WVW� +-�m�J��2�l�ԯ����Iq��w��1s1��KJK�kjL6sN�- ���� �u�v��.�����9�������q-�'�w�r"fr����-{y�ģ�<���;n�q'����6c�Z���Ǎ�0th�������Ǘ^f�eWKKaa!���TVUq�KK˪���u����p��~��N8�d������\�SO�����ߝp���M�n{����k��A�>���3���A$)%]�P���U�i+((�$F�C�p[$���%�����KJ$S�g�~�tIWWWQq�ɓ��5�W6�I��b�Wڸa}{[[[$��m�H(Rv(�DZw�h*.))(,Pe� D'O�Ou�������x<�1�H�17g��TU �����z=·gĒ�[F��г{�%{`[c�N;��\����?���O���P8�H(w����c��p�-Y�|ɒ������uk�lkܶ~��o�t�M����-������7f��f�=fl�+��S�<<�x��A���MMM���:�z�Ν�|6YB���DB߷@DrPN菔���k,;����~���?���#f�ƍ����E��%�-|��λ�B�ؚU��qq�y��7^����O>\���%%�+]͒�O@�傂�x,F����nm�Dv�j�4u�Z紳�f�Բ����^+�(5flr���݇i������z �I�kr�3�t�?9d>���D��կ��3�=����z���~|�eO=�����[n���.���9猱�����>"8h�w.��7^#��yf��oы�?����jIUU��i��93�����U����jii����{�u�i�M�;��( JJ�V�C�?����� �"���Z�QiYy<�����"��4eꈑ��ļ�^�4yJYE�����j".|��:�;:��eYVWH�����:����_~�yUuurNe���֮!N�x[[�����������yGuM͉���f��7_{U�����)P]]���e�6l9zL�w��������Hɜ8'�i�}f>����_�o�����W���k~팾�������5W������G�?�٧��uw|衋~2��h�%D�a���S�EIJɣ�=N��JDK>[t�.�����8��ݪk�zŕ���O>�����ƌ}��7�n�\\\�i�Î�������p�!U�U�u���|�~��_�l�� ɗRßF�������~�sO#��XwG{[�3�x��ʪ����/�,n9��8Q�-�D|��A,X0�����"������A#G�~��7�n�RTT�y��C�Q[[7b���_�7��c��˷oߦ{��=��$ּ�i��M��I�3�:��*_mh-�d�[�V^�����ށs-�ߔʇ�L�$�X��'�����fM�:��g�8h�g�m�ÈhH}�����^x.��]YU���oڰ�{�?m��˿Z��/R_��wkjj��WW�����=�0}�28\�s��O��1�(zXm��ۛ}���#��?����y����0b��i����:��=���u�hɢEK- +-�Ã��{��h��U���������2��7�����p�7�ʼn�볅�kh<t��c�{��s�<����ZN��O\��[O>�h"�(*.>�#����o�@������g�;֏/�[*q���C������F���sbĈq��ޤ@ӣ��ҟL�☟�{���q��Y�g��g�~�w����O<9��'���+����WN�2�w�y�����O~t㭷�d�� �9�T��[��L�2�'��@%��4i���JB �ĩ���'�_��DT[W������K?����/�z�uu?��j"��N@�w\�EZ[[[����0q���]]]�Z?5uu_�Ӡ,s��M�0f�����<{α��>���+�=6��+MG�&�ˋi(\��qp��������ܣ0R��M&�dVg�.1��d0��ntuu}�l٢O>}���6m�x���r���iھ����|�M7���{9��S��7mzuu�ƍ��� +-�Z[�<��G���Ϛ=���F +-����~w�u�����3���_��w���w��AD���j=~���~|�e��%��ӦO�f�i�D֯]�{�.�Y�d9�d@ +-$#9�*�Uc�P�>��n��n͚��FcFC� +-CZVV""Y��6�$I�dsޫC�����2WN+��3b��������dN�¯�7f���m�5�Q2Hu��[���K.���;j�ѳ��=fl2�K]�~����/��������֛��o�?�軱X�?�� �^�a��__���s�U����oo���������o�u�9綴��5�$I3fI�=)ugkk���ED�u�w��Vޥ�����)�8e��)St .�� �ޭ�}�To/������>����@/�$�-2 T>#�*3ƒE�����,ݒöm����Pu���� +- +-�h��m�pQYyYG{�,������ΐvܬ6m��偃 �6�� +-�JJK�;HC��������<�#�.�<$�)����#��®���� ~���������P�'�|ON��ʉ���s�+}}G��c �O�����ߞ(���U��Z���������3�D�!@ӊا.���a�)Z��h�8O���/4 ı���8��5Г/y������� �p�I��Li{�J_+ GYwh{�Uہ��6�t����̖\�X�g����H�'9���P ��E��_<����T5��� +-�%/!������#&sΉ�;�81m�(#�1s|��@����D����i=� ��%�]��,��5�*_0�3�G�#�������������U�����z��eR��j��̢�q=\�L�"J�� ߿ ݧ�I�dI*��k=�i1x�p�:~w���-������N~w��I:y< ��������9���'�hR��z�?�<��7�OI3BSx�� ���� �IDAT�ʷ�V��:��x�Ż����\����7�e��MӋu��ң���KC!\Q��\�Wm������������s-�Ƽ�7�m +-�W�9L�� +-տQ��;�9W��R9x +-L�,:�w75��"~�*�}�D������d�$j(Dqywז������������i��ӟ3N���ss@��*�� �"��-�G��ur��t#V�����)��z�:��rz�ɇ#�U�� +-%��x��q�J�+��}�dؖ.����������\ߓ� u5�����&e�9��P��BqC��Tr{��s�B��f�+�)k(�w��q5v�{��b�pcv�z�L��������e�y2�G;�W�VѲ�3b�<��8�Dk�H��r��+eM��_�U������rg����>���ZԎ����>�{�N�|>��L�? �������#�9��VU5�ڤ�� ~D�1��s�}����n�o)���a�MF������y�s��k9:��;Z���-4��ߦ����$b�m��bƥ�)s�4����w3_:եM͚o͉���uK!Y��:��w�::0o�l��^�;n,�❹^gGI�~f��g.U�"�������yB!� o?�2t�����7R�8ԿQ� )gd�4/h#�ӄ�^�H�1ά�������g�S�;���T�i�] �͖�e���qn���<�����E@D"�O�������!L���qbLO�Iɼ�*�]���l��E�v����?��0#��X���Uk�����ON����:��ά�M�}�*��i���ݝ�'��yv�7Oy^��|��������r�$��χ3�����><������D<ܯ������7��kn�&-}��H)�.n��7�_�E�%��QL�p/�6���N�c����N�"=R[�2;�������F$�k_U��1�9���w#��W�dr"���d?b�o���P����7kDn��jN��w +-ůy(��w^�"ݫ'ko��Y�-�wJ�2���E���o��g���{������;8���p"Ƙ����XeL;�����f�o^9H��M�c��a&�O���K$6,o��~��G<��I�u���<����\�̿,�6K�{د�Tz����r����#2�k� 2������#8�r�H �:�5� Y��t�OF�?�տ9D�xJ�]I#A[0`�5a4'��w���8ފ,Kn�v�mW���g1���L��/G�mf���[Yj��=�7~a�y�90�:��������<��ɜ��vO��͎� 0m��%<7|���#����;�M��o�U #p�,�~f��f�(�v��2֔:��H�{\�-�.�~7�oO(j���~���� �J4�����GH�����<�l��d���O����xj����$;V�&�5��&�m{��k��`�"0=��ͅmVخ��t!����j�P������k��b��˧�=�������mM�7�1�������dN\݀�IRr� ��T���{́oHy��p5˴XC�3͵��i�d��;��U�����o���q�q1�:�ѹ��Rbn�=�T�)��a�k�|8������ĘL<);����{Mܛ=��� S0��4��$��h����0L�w9ӫ�ؼ�Vt�~Q�����;��!�M'j�$�t���V����7��l�f��x_.�4�F��Ү���Ϡw������M�I����j���ϵ$��L���M��Z��F����,� ����40�!$�ݽ.���,J[,��ɮ�q��g�7�b��۵�;2���ɗ�f�W�j������I&��x~"よ�3���~��������W=�����k2���_L�}��I�Z���Qb}畣�W2�??~z�����\��iq�����nݰ�g��*����߶'X������0����}S/�C�&ˌ]�FNMԛ����gf�lD�[��-���,�����u����� �\��z�ց�3���3��W�\3��[�NFs�4��Hee7���M�ĭ!�����r�H6Kd-�%Y'�ӈ�<K���JL���������b#��U���B7����#��c�6��;����n`���*��1��f�[my�\bXW./�������K߂�Z�j0q1������.����J�x���U�nN�Ov�|җk�=�tao�`Mߩ?%cw/Yc_��%2�%&w���{���/6������jz�\(�&��� +-��T�xA�W� %�n��Ҙ��B�������Q2·s��ε�w�0��^�I4�9�uQ�ޱ'���u�j1�|�XI�W):Bq���l�V�/T��U�3�e�:�+�9X +-���%�[0C��9>b�����@NH�"w�8�G�u�)�M��?XS���ȞB9Xho��4;|��p�[s�����(<����� �5�"\<_�Xz ��7��c�e���w,O�?m��6W��Q'�����e1������ �HL�9�$�����OV��R�Q����m #&�Fs��y���C��Pa;��?���n�?�7V[�1�ݛϝ������g�e�;7ը�?%���{n��x�����r����d>d�Of���d1�%ue���5ҶkD�Ԥ�\��'���)��GZ}!&��3��:�Xk�E�����Z� K��k�cm҂�|�v1s#��wK�]L��С֯[ZZRY��[o1���������N$'�/�O���?�%<�d;��@�����.H�@�k]2KC+���C�&w�;p���7?s�y���P{5�b��I�=������E��e����¢�h$�"��>�Tw������o$F��~n�ϫI~C��3c�u�rPiPÉ�=��v�/D8ƍ#4�Q(��.F�k��sϹ�����HI�rA<��s$� ܢ:������yFQ�x�#�GpYm���^3 ����*v��*`]���H'�Ū�W�_nf����<q�©%q�Q�+x��uV��c �����������y<�%�9t�C�s˝��.�%��MY��q.t�� ſ�p�r/NU���?G�\`�A�������s�.ϙI���綝�i�9�p}^�}�,�d\�� +-C|,7����k��7܍8O��jΝ!����� ?L���H ����w��:��.�`i��;K=T�E���.=s�L� �}V{-�����\�\&�t��h].���t[GG$�ٖ3���J�&{ij����h�?�����>��;��p��OM���<�M/5�i� ������X@� O�q�<6���r�A&��Le�1=.]�)�}¡�*g)����m�;E��������x ��χ�6���e�pi8\گ߰��̈́?m�"��5T'�A�8�d�J��Ѵ�\_ضB\ɶN�Ѫ ������) N2q�f��y��a��G?�{��ӓo��IG����M|�Q���cۏq`\"����� �0Rd����3ݾ;���u�FZ������O>�n�/2z��Å2l��wRL��bAߞg2�������%�^����4/w�ZΞ'�f�3�X����?����@��4B��j��߀�o�3"?����@^�ĵ�����v +-�����Y�[xO �<\p�^�ܑ�I z?�_�$�맓������!�̓��D"?�}�7w�k��M�F�c����k�����n{���H�����r�DL&n�u +-�=(�s� +-��P���Z����6\g���M`俋�p�s�KA=>�������F$s��+��][d+b��/--P�)_֟���;!g�7g�~���L�v.�����\��b����������v��T��A�) �)��������4��@6O:;���?53 �������B")��wU��|�j�C��<끑���Og�s�7S�#��y�8O��cX������I�s�s7_�g���&. �K�ꆥ�#7u8��Է�`����^�BjZ�@}�;6���c�ً������ ?��I���R�t���Y�H_����v�W�{��q\Q�}ϻ�%����l��j�^i�����(�d2;��C�=n�ӝ\� �|��B�;2S�V=���#w��>}���{���������1#���̎�4��S�zx��Z��O+X��8�ݹ����Y�{�V����'z��|��������������[� +-��}�����A�^��v_�A㏼{�]m�<���^4���+���Af�^����� H���ff��~�<J�t�k��g|Obr� +-5[J4i�d]ئ�0�fA��ߛ#�'����@�a�S����6�[�v��.ީP"@rP*�I.��l�ţJGTi��]eg[bW��"�T�-Ԕ�)��$Q�b�Jg���%.X�9�.@�B +-O^k��sU#s�>���\՜�sE�3�8cĈ���d�'N����~atGD\"��&����% +-�t��������]�c����zT_�|ҷ����@�p�~�������M�_u}����]�� �u(mA +-X�D*mSZ/�6�7��� +-�6κ:��N��<PӖh�Ya�T�M� ����%xw�����U��;��(����(�tpJT4'�0�R�2��V'S�hK�&������-D����C}Z!U�VvQ�4�Yi$"��qW�VJ�v)ۉ�J�עlW�<c1"� +-ؕ�F�ʤ���.b��XQ��Qu`�:\��t�vFD��*[���J���FDA)Sb��ȵ��;��R�ەhҵ��cD�_phs|+UԧDD!��N�����D�lSv�OKYy��!�yPs|��(�P��*��;��60hGbX@!.S ��*i@�Ҩp�\�ݞ� �� x ��W������.5�?�����������ؼ�^�Ak����Uԥ܇�i�h�����=ʕCiL���ٌ%�+N1" +-���DSU����l���*v�+�A%1��k,�R�HQ���\{�_�O���IDĘ���^�q�9� +-)�8#ƈI�$&�� �x\�幵?M�:[[S����t� )�������P������|�������d�%T�ь�T(Sa���<f���p�� +-cD�hnzy�*����ݠ�$ �r�n*0" +-ج��m}������������p�8ӭ�8�P�8*��JM*,�л�`|Q�y{M�z�#�өl���Ų{w����� I����\���+��?�T�Y%�1S�[�E�yַ���L�6!���ɫ��������WHtn��������c��� +-N��R���R�d�csM���~'�����} �χ(��s�i�?�+u�>�C2��F��62���kJ�_�����d��$��n.f`�u��z&�� �����P������AN�ͣ�;��X� +-ϯ7�L}�����C�����^�)���iF^sK�*}�tg�w���T�Y�������������uH +-�5lz�:�����b�$��[�[F�阾2��hlZ����� pΉd���T[���Fۺ��DD�ԋ������r^z����Y�Y +-rJ������cD���[��sߊ�������S�ֽ�������gDDy<�����E@b����R�3��ޚ�!��~^���}��g�)H��}�����������le�����������-k0bi�괱��p�=3MA�����tR��%����7>s�����>Mk4"�ͦ۸������w��%��3�[�y�V�;��tJ>1��ە����� �|�j�L$�^�5���DKC�=��>�`%���A�.<���~_�p������x\���K/��B��K�U�t5�%��dg��{� +-�?E��P K�_��oE������s�˺`7?H-o���.��هf���@_�ȑ��ѭ{&�����������!1���� +-3ixC��L��D ��]�{��:��[{ރ��"�����^��*e����l7�&�:�2�pފ���M=j�'��*%���s�2�R|\X������@>�TX��~�t|8Tٳ3W���"�p�B{������@ػ�%��2������������ s8��x�L�1�B�iefo� �P����b˖T���z�>D�|D���FB�!����ra tV����cI��-A������pPR��~O_rS�55��wn&����:I'I�T��e��Of� EQ��`aaa�0�����j���������;2cf��T�~s��T�aAaÞ��(A��c�����Sf�8���%Q�BD �P�>P4 � +-uK�@Ѽ�,��p\!����ӄD���# %s}"���7�l�Kf�qND]+T�������XP{��VNg��c|�|�'��xlҵ^ ��;���������\�zf�^[�:s��(~�?W��ܙ�Ғ�۫h�i4���I:���� +-���mk���sk�����rIGw�����P�i�d��l�܆;�q���t1���L��kxz.ÇR���t�}��?s���?4Ǎ�:�������*�R�̈y8`Ň.��.v�Q���Lup���w�J�]��˴�LP˿ݒG2s�{����{��hu�W�������%��2����K���`Dm�M�nR�)��=���]��?}o���I��R��RϠ����n�6��o�=f3� �������ŻS�~��`�Cn�z���1��C}�v��8�m@����i?�>?ק}���������������m��S��؝����=r�1OY���P~[].(��[0����؟�����W-�t6���������hBfL���g"V��)����K�Wp����ޣ���#�Y ���3q��K��c���F^�����ޢ�'R��8��J���|�>�A,;�$���"����Ɔ��R��|>���f�1&Yj��=�������9R�����]�,���v�;/���d���9�Yћ��|�5J����\�✋MG#�ʹ������䏮D4��?��i:�����YP���f��/'��!,�鹇da=�"���M���y��'�������.3&y��m�v�Iӷ\ە��0�n/�O�zn�8�!K���3"��?rv�*�s��`b�~Ng�������Ź�D�Xt8�{�[�CE��̘g���g�q��4�3�\G�V!��x���<���G��8�ll������=���#����V�h�t�g��;����Ѽ�{�Y��,u�K@�d��c�����؎��L�����<�Hf����Ӓd.2)�����-U݃r<��\��ڵ���?3w��)�X뺼��w��>e�~��������d��K���8�e/�=����w�����#�g]����!6$ӱ��I�SO��%��{8+�{������&\ �b��e�nfq��D��q"�L?�t+� �g9�_�Qʓ�R����K�� +-��������T���'i��x%oTw/��u��7M3��_��yE$���{�Q������������>��N�Z���>���G�Bi�,�<g:=%��9���������rV#�͚��� �u|������}�]���^��zr`�>L/�'�36$������ �b'm^���D>iv��"����-�������@�Q��L��l;��?�q}��k�J�i3�)z�Y��������˜�0C����U=CĽft�o��m�gB�D���g�㬧����� �0�8�s��H�^��MI���1�}*〈�{�x.��������:�:eι�����PPf��/�2=^kob/q�w�b�ю����������/�����K�$����1�Y�Y!���2�xo��5z�(0 _�r��ȞWzoB����� ]�9���E�0#�(�>��SM�L���|/��uxFT +-��h���������%5��UI��<�Ls���|5W�"k��X�{I������� +-)2�Ha�/AN�z5�2��u����s�Ԏb�?�}������ػItq���f�a䓌G��t}=�EҞF���i}�X������3���^���mX?r����d�u}t�ۏ�g�=��z��N=Â�����@~���*L��r��'��=�d�A?I����>����@߀'H�<��y>/�9}�#���^�6������J���җ4���b}?�=�����K�$�P�� �IDAT��������{�����k`��ޞC��)ѽVnfa�=���1���w���������' +-K�uz�4�FXJə�O 펍 ��?��m������e�����}�������߯�K�6}�*J'��l�u���%�^L' +-�����D�ĺ����/���p{�� ��SD{���X��n�d���f��_������N,�価���(�$�<4���]�{��"п���G���?G+��b��8������E��C&�R�9��Ovy�_�1��&�����|����:�\ۈ����^QyEE(��w�-w�t�~zɈQ#Ӟf��,�T��sg}������L7e0�o�����}�����/C)�O~�ӟoX��{�ں���G�^�j���^?q�����?Z�rՐ�C^~�E���!��Nߏ������'���+g̚i+���^�vm����f�࢙���if�U�s�o_�d��L�OW�g�h���!<�����}����ߟi��:� Q<5f�Qsf�[�+���6nؠ߾��<|�"�h���C������jŊ�Vp�lk�6a�ĩӧ�����r@�^�r�=��]����ƭ[�=_/ܽ{7����˾�R���`r��X��t Nw����*�|��s�l���aX� +-Ғ��9�S&��.l������%dʒ0hଣg���m��MW_������k~s��'V���͛6�7���jŲ呶�k/��u˖� ���G) -x{��o��E?�3##G� +-����x�����Op�a��-����[b�n"�b��Z��U�#G�ry�l|V�;7���V7?��jFf��'��ل��h5�����i�4^?���m�����wP��2c�I���\��k/��g�ׯߴq���^?�~��\�ْo�6W������{&�7u�����+6�_/I�O����>z�]wr�a������}�� �Ι����.�(��i��|�m�D�n�ڟ��ˮ�|��D�$sO8��}#��>\�A�h~f��0 lo��}Ƹ���{���~�F�6�̷�xH�~�����>E<ё"��=��V��������ǎ;�axee�_�x���.缾a���K��O>�IJϿ�e��o� +-����ٽg�� ��_��K�~��9'w��g꒘sND˾��чQ{ذn}㖭��ٕ�f5�o�d��*ho��β.��w�_^��vu��¤�7��f??�"z,v������U����qC������e�̘g�o�,I��W��g?�d��U�<m���������������N�/�H(�������%?4d���?�࿏��GdY������2{���%%D��c����'NP�X����F�;Z�}�y---̤�����!"����sO=��+�Bz�t_/��<�KU�;\��\�hx����- +-��Of�������2z�r�ұ ������,� �]$[�:�UTV���?����4��]r�e�;�A��D�јqcr�?;�ه~��O?�ܓ��ٽ��C���7TUW=�'��c�<�Ѕ?�މ��Fgg4V��/"�Hk��'�>�':�pu��_y�(\� +-����)�Mݽk�������Zw�uw�%S��Z]S#���T��D���ܑk�ԛ�����XgZ4�Q����*���q�,3�k��+z�T@������]�����0A�f +-�`�-��KI��x���g�n��h4���]�z�V������иe+W���yZ��aS�M]�r��(���7��� �x|ҔɌ�+--+�'�a�z"�>\��������D�}�qǝt�?|�ο�]T\��o����s���=�z3���"oxR�;�qjl�1����7��������&�5�l��(�V�L�K�ü!>�|pJ�����@�+h���nv'��������g�x��kW����bݱGxHO��d�⯾\6v��IS�L�4q��q{v����\4r��� +-��;o�5���'����ʪ*=$����2x�!j�H�MQ���J=`g�~S�i�<�_z��|������ʬ���v���ʱ4��C�&u��1��a>Z��o��u�O�n)ŕ�o#�Y�*F�1���������F[w���ȼ֗bK$�w�|km]��'�8h�������/��˟����w�i��n"�;��C�L�ZU]MD�HdŲ� $�o�q���u�%����`��� R���M�y��s���ղ���kjtsiY�ŗ]rۍ7��ܹ�Ӆ�_}U��=>�N܆y�����$���TU���3��l{�L��f����u,�Z!Y�f�żg@x霷��h������� J㵲�·�Fu\ +-0̂�o�o��@�����������i9���xϟ{�_j9l����K�|�x��+�+*n��6��bU'�(ʺ�k8�@F���u� ����;�S��͛6р�v�A�2yʔE�.�$�+<��]PP��U����5�b��^���Ik��]k$��;o���^ߚ�ӴO@���̍'��&M����eEK#�������p�pQP&r�~W ,yG�9��3N8x��p�n�4ergg�捛$Ijii��2c쵗_��_ﭭ�;��Cο�� '655�U�]�$I������Cf�-^����m��)+�/��;���}�]*�/\������^|q���e��D��ٱ|�W?�䝷����>��3�n���n���5fL��a������*).�7�������-͏��I���VK�q�&c�08qK4?%Ә�]�9�ߴ�`��\�1�p_�1&��F��¾�l��sA�i`Q����� /t(��5��k�~J���������S'�@ p�տ�ho'���?��;bƸ �G�e +-aD���^�@����G}��e��a��F���5�V���x���5�D���ǃ�x�����K�"�W���/=x���N>�����v45-���/>������z����."���kh�|�TokGw��S�[��Y�u��y�4�ny�¹�c6�r_d ��ƚ����Oӯ�i� w�b���9�������8go}�~0$;tkʪ���7nUQn�~�;vĺc���"�����(���P8H��Y,�$)QG{{Qqq<Ȳ�dƈhgs�*�]ކ:::Z����O��l1M;��bV,n�2�Xb�1�����b �(4��'�J�s���Ǝ=��{�9��������= ��w˷eU��ݴb�a�D���Q=F�j���zVoR@=�K'���h%bǵ�J��O��{�TƤ��j����▽��w�I�d�km��� 2�}�S��^ğ\���z������� o�%�d����#�v�]��ܩw�C��G��֟ݒJ��D�g����U����˙�Ē��ڇ���Bp�L�C��Y{a^������h�z�����rC<� 1n�|f������\�r��֭@�;�%����݀qo�Fe�P��dTI^q�gˉH��oL�s.�����G'���~y~8�����*���㓱����I�������䮐LĬ�v����mr�^bQ����wf���=����[4a� +-���n}s�,�Λ[*���sƙ3%'ӷ���A�ޡ��r1�����u�q>���>D֩8�)���������"���!:���ő�ȿo��҇����.�J^^�n��9�U��H���uL�y��Cƻ��\�\��_�c��u���i�B�����-��m��:"������-RB�-~xo�/��z�ע6�.�2��ַ�uA���%���x?v���c��}�ԛ�ssE[m�t`zZk�+_}���Z���7�2�/U�~�A'Hd�2�I������@N袸Lg��=o}j����r��_��}�}�#We�������h�Սn�w�Ϊ6mω��Ժ�`�M�5��~'��&i���C�pC�h�<����*��������l�)'Y�$ ����=4D(��+�G�;�}���#�(CD"ޞ5Ӽra��O- ,f�59���T��1`����%$J����x�v�� �����rG0��!�����ډ�Sq���݇�N}b�����N��~&�n���O_-�Z��αf��ڼ,���l�,�C|���)u�1��O����@��������.3%c1�7N�H#��i-��S2%��1qos��.�u�[u�(�����؊,�-b�t<���1�|��������������c�-ʹ!�87��w�2=�W%��ϨbZT�'��:�tj� �Z{���s���W�=�2�7�.�}��5n�n�i߀-�> ��slӵt�C`�|�� Q�Q������'x�dN܈�I�f$��t<�vZ�!�M[N���JDF\7D���ҞA^��ҩ���- +-Tlp{K��̸E���^��Ա�N��bJ��a��?3G̎m�څ�[o��ð�o�n���������/)���_��&�8iꟈL␑I�;C�x�'����u͎2y���!�2�#fD��T��-22�1c+�6���9�oR����۱{�SԵ���{��}gkm�ޔ�L}�������?�S�����s�o����9�#_W�F��)DH���G՞4��t � eQ1�Q�J��Omx�1�6 j4t�Z���5��Cצ�F�����< ���xc�z��#� �Ю�-s������oXA���|�9@'�0�ᭊ��k1"����9$5@W��&@넛�&#��Ћ���Ah�9�ńu�������́E��]$����D��Ū�{���++iM���S�������� _t�N�����Ua��"M������@���,n��<� �}(n���b���*@�.jI*آj!��u���+&���oR\x)��EY��A�d�"��������( 1�s��y���5Ǻ�O�,��e�fs�k�2\� ��dnCv��-�sk�y�1`U����m�����SLJy�EfE����=�� �0�+!��!���3�������@^�+��~"���%"U�jYw��<��=N�(۳<Ա1kQ�$Q<4^>�KYǛ���q�V��n��M�}�`ѦS�kW�q�e�� ZQ��پ�,�T&I&AA����� װP�d���dӂ���z�NW��k�P��A��m��j t�vUX{x{鰘&�� +-�|���t�A��6��Uk7o�t��#���D�Ҽ��K�qX(^�ɢ��;g?�Y��&�ݓo�b�1v�:���q�����ھjif���EI���.}�����>�R,�J2�G����:�����m�3"�� +-w�/�"ݫtS�;%td�dX��kok�2'���4�$������-/..���Q;R?�1)��JD�ee���V��v�����kׅ�+�ͫ��9�ƨ�7/o�g��AA���>�}Jd���g�sδcZv�����mmm_�|��x6G�To������ 0FR{������) '"=�����)��?(�~�S���P�݁��zP� �9߲i��� �H�@ �t�b������wdY����>�X��OxWWWsӎi���1 �b���k��}�.��N���_].���$֯Y�LJ�h�kĺ�7m����oh1�-7��a�dڽk����F4�nٵ{�." +-��� +-��֮Z�z��q�'�Z�b[cc�;6��&M���t�g�R��T��E\�C������E�}���\�7k8��V��k]6��ѰCD����^�t�=�C�S�����.�z������͍���0���>�硫��5u�����������z�����[�9oܼ�s�t��/�,�G�2}�I�M�� œ��2N?Y�%���[�l��v����{v� �-���3N��d�S�ΖW����������~<��3���?�����nok{��gG��0j��W~�ŗ�u��ݱ];wΘ=kԸ1��֬�oVTT4dX}�-G3��a��������h��_G;��N�7]��y<������u\ם�ާ�� Hqg K�dIvdG��ر�q���y�~�����%��e�du'v:i[�X�d��$K�$��L�$@p�c���Cݡn�uq1P�~�]��:c�;}�>�����@G�\�R$�.��4��B�gΣx=�8���no�~�ZFH��F��؛����s`�a����Gvl��ݓBr����G=��$"��ߐ��4����R�_|�ȓ�re�cٱM�^D�\N=9��5�� +-Ijc���F��G��;7o]���ޏ���?�~�X��r�Qcoo�/>�����?��i��8WW�R�V��W�GF���3\�C������/���C�~��3ˢ�==9�s�xay�R�X�}mb�}��2�|���rEH"%���� �E��w)��������ݾ�>�����0u��m�<1�gֲ�<��������F��G�K���9]�&5w���-c[�ܼq���ɧ�旯U*�Ņ�e��������R귯�ADO>4�owmy��U������N�Ȧ�M#�G'._e�'�r8��KH����q]e����6F$h}���Ț[l��ggn�l�dLb{d�����}{�<f�ܽ����]yѵ`-y��cU�/}�e����%Z +-˅��������M�|~~~����R�x�Ν奥\>���GD�c�C��/x�����Z/�1����Yi�MK�+�����@a�cG_1߲'�]<�����d��}53`���������UI]�9�0""RXZ�1�Ӷ,"�ⳳ��?}�Q�w��\��9�w^���'��^���={khx(���D�犓/�m��������+5�G��\� ��������H.�[Z\��kZ�_�w���/}��sg�V+��ne(�Bt�������jUE���CLj��:�s�.y��!�P�/\��{��COt����h���a_�{Y��80̿�j�T?�������?z�tde���z���k�ǪT2DT-�ɿ}�տ�g&�J�.>��/�t#[c�~�w���r���;�����2˲>�ݩ��ݶc[Cm���t�BB�vn�;��`�̩Ӈ���:�g�^��1{w� p�'����E�J�A���7x� `���Yg|j�a4V]۶mf�NNA��7�g|d��:V+���o����>y�9ga�lڴ���#m��������io_�䕉�����D��̧�Q�@�\z��B���ܼ�����?����g�4��� ���8D��������t�Ѿ��z�5��F�n���r�~�y^^Ҏ��v�ɿ](�57��o/; 1��7O\�x��F�Fz�?�E#��OϜ��L�������su��,--ё�����TʕO����7�)��?�_�s>ޙ�A��w��ź����k���+b�k�0���^�������MC��ȉ7�Y\x�Ϳ�QCv|ⱝ�w��so��Ɓ������2���A"�䃏n��,�M� �������۴�Ǟyj�ֱ��^":���'�~��#O�ٌ4�{(���4�]%�ahd������Xu +-v��C����B=�.4��U^���͂2���,���{p��v�������>��o�o瞝��/n�̾��Kc[Ǵֿ��_��?���0D�R./.,������9��$�\��G�~zf�}=�[���y�����Joj^_�� h�%^$U,;�ܻ��wNܞ����5;s���D���϶n{dxt��߾3ye���J�\*�K}��D��eEd|��/�l����ǯ8����U�^���Z�n�r���ݻ���4��_96}��a=����t��ݮǟj�놩Q0�"��Α�>�������&5���D_�_���=�����7�[r1��ss*gK�q,�F�k� 1�R��?6Lcq������ū�J����,---ݞ���ew��w�O}�Im���O���V�G��A��}�����{���)�HH�r��W_z����+����� im����U����]:w����__%"�0����/��"���מ�����g�O���w��o��4�M#ï|�;���S��}�g�>�SЪZ�W�^����r���ڣu%�� �IDAT�G�� +-��L�~ā֓��������a�Cx�������0,Z��]�/8D�G��(�o�UoF����溶�zZ"�4^��W�]��r�ʧ�"�=�� �;´����o��}|�����,����??��ggw��vu�ԇ�{�+�]��"���<�QZ?�nj�����9�ܷ{����1������4M"�wp�+'�w�}�_Ѧ���?�}�Sϵ܁kyiiiqitl��`o_�2���/�>���~��}��K�Y�E<�"���bG�;�?������3L��V֏4����O�u�(�FK��K3y{�$"���o+�X4�Zg�U�X(X�ED�m/-.=�_( +-�R)�� n�r�J�P<��ѡ�!!ڹg'�n�+D�����>s��#O{��摏O~4ww�?x���'\ƻc��.ȷM�B����q�[��gŦ2�6N�����ھ�h>�>ymמqj����'�!����k��� `EtK#R����ג�ot��� 3�����tC���o�t^�tߓ�}O�� +-{6�,����/�����_���_�|ndl���c��ƕR��̝���^{�{?����v7y���{w�~폾�c|��<t�����w>�s�NwOw=����}i�.H����vDwP8T�rn��K��<�@kEL�bǴ4۬���������2_��+��E7z�흈�����F ���������e�����l�{���ou�$Sg)4���r6��d�DT.�r]yOy)K]�]-�Z���6 ٶ���Z�l�n!�%��s)���!���;�<��Iڇ��+�o�F4�C���3LD/<�t������@z,�~��q��:�b����O���4���9�n<L���.O���1G6��a���F�Lh��6�Y$!i���2��_��z����.�@_��'"�!�����_�4���on)][�������� �4�7:�; �ץW�5�'\�E�z�d��#�����R��#�h����p���������H����kxE��!�����C7���E]�W�){�4������@�Lj��J�^N�K�{4i߯�,IV�'r8V����D��CU>QKL=kp@�k0��~�t��^<���ե�ni�o��{u������f�����e����ߝ�u����S���h�QLj2���n�W����i���ЦZ&�� ���r�^�n�X�"-���9������`�0�D�BPB�g@�@�Z[O'���WM���6� ��t����$!���m��K.�-�Mw��D�*�g�Z��������k���������(U��gO��� �Ľ7|[�85wr�VB�TH�h�%�d������7�~�=��z±j {�(TߢSD���4��y�O�w �������|�l�-������ɤ`#��W�9蜠h�ȑ$9�p�E!���B>�z�i�%���ڸч��|B 2�5�*��������C��ox�Vz,@� +-����{����ԕ� ��F�o��߂�e$c�R���K�ƅ�|s]Q�A� �i�Y-�����:�"߿��U��3�~LȪ\`H�T�8�%�|�f;�Mh j�|��ųV��DZ��qwDB���������2�������X��k�~G�>Lwzjc�DK�K��_�VEݺ�P��=a��vD`'��7h6���C�B����| 0#�։Dal��=!ۡVM����H�O[Q@h@(�Hh����n6T��v�ܒ�Jpw,dwP������i��I��}�2������3��e"*��,l�v��}V.Ucb}ܢpe����T�}�^��}��5�58���;)AV���~�����5"U���`���s�CU�6�t��w�͏��x����wm�fz�z�`�������K_\|�/v�vO^����4���m��d&�ٶk�s���>�1^���+wo�y���a�y9a��.��90�&<ٷ�i��Ŋ27B{暇���Xϼ��������*]v!��M745��n��l�Z��Ή��iR�R9��ək3D�`~a~n>�ϊȭ��o������F΅���o��s�v�̩>�l[�,�>��if6��#��Ձ�4i��|h-����� +-DT(�~v�[]���x��#�B�%?\���������N��Cef��='?�p"{N~h�K��ӓhמ�D4?7���k�&3?����M��u�qO���ٲ}�7NE�j�{t�P��4iU��g.X�����+�J��LMG*����'�O^��V,j�R�>q�R�8��nܜ��w�/.<�6qͶ����kM\�1=[.�ݚ����o�;;3{��_���g����X(\8}^�G"$-�D[k�����@g`2��������ߒ����c�����7������%�Μ!�k%��\ܲ���\*���if��{��M]���ڲ�ݾ7ww.��仺�7 )��y˶-���7o����^?��"���q��s�go����.M]�<x��fO��|��̵���'����ͨ�p��ۯ�y��]{v建���7OX�5�Ȗb�������s[�o�x���Sg���͙��?����gpӠS��}�u�־��L6sk��3/߷���sZ���ٞ��;7oo���uyN,�|�B3{8�c_�Q�����)��W�ڍ�w10=�<P������dY�WM��dU�f�jd,���B6�=�m��J�H��g�{*߹w�aD��e_��D���mMDwn�>���_�Z6�%"�R�,��a����;wc�����L�x��NOM�ؽ��:�o���������m�������#OqL����o|�Dt��S_|vv|�8i��3�_y�+sw�[U˶���V�>����?CD���o�����ݙL&e��������0�~�ֺ�b<��=Duџ�һ�h���k����,�% ���H��>�����?��s��g�fΝ>GD]�]/|�M#����K�����ZB��[w6 ord���;7�u.�s쟖}~D>x�}�j=���ٕ�Zt�X���sNޙ��?П��,}�\*߿7W,��lwo ����MO^߽Ox��"o-������V-��?P���l��j����K� b��?���O�l�kSN���ѯm=qi���{��f�D;v�8p� ��c[��ܼ}��܍�7N}p��cU�D��|���c�۶s[�+�%P���1P,����~.�+,/Ǖ���T��|W^)U�9�ݝ����U�D����䜹>�m�v"���e��+�����n����ݨm|���I�"�)(K��������X;l�:��I�(���R�ܦ��#�v�P�~�u�O��ޖ��/��\�Tr��������w���CDÛG�|��ض-D��߷���}��;�������6 �;��y�������� x��j�dFce���0M�� +-W=;�j�ŗ��J����F������{�����G��_�),�izj���ۈIk}��E"��뫖+�y©u�����Ȏm�֚M���~�k�G�6�������2����.�o�o#SCk��[ؾ���{�d�P<}�twowq��k����0}�\n|�n�$����'"�j]:w1����������G�Bz�aY�)�lk���@Ooύ�7A_,�ٛ��ܷm�6m�o����ޞ�^"2�?8@D��C�O}~����J�i��ӟ|>�������F6�8A>{��䃏<~0������/7��������Q��YJ����>�ɶT��I:y���L����<.�j������w�h��m'�<Q,��NM^�8��a�tE�p�|�V�o��-��|k��o�����l���E�Uq�#�,A�c>�Vx������t{���ݻ����ssw爹X(:+J�b�Xr�l.K�;v��<z�O���r����t���2<:<smf���N+�i>y�I"2M����������|>�ؓ�C� c��D���'~������6aq���p�:57u"Qf������{�-����vx���V>�>W�Z����{s_��?���z��g���o~��/��?��oG&b�rm���ONk���o����s��g�e�ր�l����Zos��������.Z�8����h9�eۛF���_~U.����_�v�Ȧo��;�و�<�����W�n�$���s���f��ЦM�o����L]��8y;�4g�������ӓ�=���G��H�@�|�q���������N\'=�_���O|��O��d'�?>?��}r�ν�~��U����_ۺ}+Y�jo_�s��l6kU���#ggf�\�\.�/��tዋ�c�G���sD��ϼp�Z���[fV$:�& +-R:��'ڽ��=�"b���?�ɟ��ID?���)�����x>�i�/��$�-۶y�;[q����<�y�-�{�z�R��_ڼe�t�����ig�D5(*(*�����tf2�#�W�e���;�l�|�R��g��R_σ�n?����=�� +-�L�o����;smffjz��dwO��|q��¹�_\����ݻ�nߺy�ح7O����}�}�}���Ӯ�����ל��ږ�m=84�`�����=�X��DD����PWn@�wU33�%�(��gv���x���?$��B��@D�N�Q_-������"bF��T����o}���'c��ؽs��f��2y�#�G���S{�UJ����]:wqz����yḈ =�³�xۮ��NOM�J�j��lw��2C��#O�ۍ��t�s-djBޣL�}��̑����A��w��������?�_�f6,�#��+�Ս\XZ��*Y��7�OD�R9[�9W��#��=��B��k֛�X|gS_N�{>A��� �+�t���O-Y������@;�Z��k����W� OR:"��ٲ��Z��[�5@�:��u'��5q�':����5�!���&�Ʊ�������̰����k�i"go�FW���q_�z{%�����倴v-Ϻ^n�]�?������#Z�ƭ^��-��b�P��zR�iW5���:�_��D�@���J�}w���������h +-����Њ�T��k'�S��EV��J�-E%�{��.�����D?������`0��*rߕ� +-r��pIT���Q�k�+��J:k����u${���1�8�d/R�����@���&���n�x�T@b� ' $i�Ÿ��j��[i�8�C�:�de�Dz���[%G%������@�df�����K��E^��M��Ӊ}�+ >��Z��N�D�VK�y��8��r�/D?�����Z��Mf�!f�ԢAW����M'�c�,ڣ��a�tķ_epYV������l\� +-[�[wZׄ�YTU������;�ÝЉ�m�|�'����)��[���u��k������Xs���!�ډ�N���k� �p*i�` ƽ����]���+Xa�r"$�`@�/=:�?�(�����Xu�ɤ�n��Ӿ�K��V�;'R�DG�D�-����\��t��f/�R"MǠ�!����������5q �\�Q\&�H�(�'���dz����Id/����etb���4�������(���Shv]�����\@'�z3L�G;�î#" +-%Ti� D���N����J�Z(qt���d6������"B&�{��@%�ϒŋ�Q� ��D�2EPtPM��� %� � �^�{s���*�����@�����lD�8�� +-;�rK��{*Y�E���9�(�3"~�mۆ7?D�'���4r�v��l���z�#0 ������U�_/�{ן��L*��KU����* MN*�[�qj�ؔ�ń�$��XQ(Q���L������?�@s�Ȼl�Q�������N��L������Ȩ׳;w����ټif#�q"�F_��BW��>�!��M�n ����>x���n��n�P�}�|� a�������µ�~��#�5Y��s�Z��<��H`3����Ĉ(�H���=�K�U����i�W�DF��.���/M&&?�}{r���Z]�� [�>��~������@Z"���G�Y��Bqqyi�!��8v#$s� +-�t�E���g-$R�Qb=���~��X3�Lt4���}�������tu��v+n����������!���Er��o9.���|b�X�P\@H��?X��i]O�"r��fS��$��?������,�<�����(��� ������Z�m1=�د�㴲U-��l����MSz�C��_�/gL�Ib�R���w3n����,�2��U-'1��b"�C������:Bܢ��:d]j��]�a�9̦���q�מ���@[ � t�"���9���D&D͋x�&�܈�({�������[u?1I�(������q�B��v�Ax7�{'�cּ&JI$����Ʌx��(�o2s��������5B�6�ħ��Xr�o?�����j$vc�pw����l�:<�]�"�4rd�� P���7Ma�@������;"��������GGx�<�ͣd�>�w�i�⪎�� ����샯+���6��HBR���姪5�������Vv���V}�ȣ�DD��Rq��t�C�W:����-%"bQ��jB�G�� e�t§V�m���$k����=���D5�`�����@[�PM�)0� �7D�%�ɶ�l&�5Z ,էO#�"� +-T�U�Hخ8vg����T�nĽ.����������M���MWW_WW�����1S@8 y�߭����dM�Ikʓ��n�$��oHZ#"I��������)i��m0�������4��D��4�D�b�����m��wއ�!�?�L���zq�w^֧j1j�$i�Ya����������ar,&v'"[��O*�C����u"��lQ��1�ǡN��;�dJY� +-�r��t��\�?��������f����uj�>�aw� � ���W���z +-"����%�j�+��q$>�����z��C�ry���ɉ�*<&$V�S��*�~�d��� �U��d�w���Ěkp�~�������q���x�`��=��O��aD �`}���E��:P�v.x;-�6�*��щ����� %��t��F�w��^�P�|�mXI�菛��������逶�MS"� +-e�~���������D�/fS#���'l"m��D���t~t?^� n�At{Q�JRQ�iܙu��\<]�������kC�ަ�D�9�� �6��?a ��<���Äx�,E�(��=C�{�/�h^eb'JZI~��� +-Wf>��������oW ��=1�o�������S�S�1%�+_°2RJ����������`q��[��H���s������o��n +-Z��?T> �&,?$�'2��Z<��j���[sć��(,i�J��1{)u�A�@������/��b"� >�����TL-��� �U���\��#�c�c�������Xw����u&MXz2��j� +-K�)5��ʷ)�:�E� ty�#������FA��Aq7�GQ�e[��܁IM� ���X��� ������7������O�z4O�:��ݹIMJa-��`�Y�������Ì������5����{zm�rl++��������`]09Z��ՈM~v�i�L�F�d^+��{���b�"������&qS��oH���AE"E��cT%a�mF��5�kJ��gb3��D?������E�����:H3.K�e�x��� ]I�z�U���w��{W��F�bc����4��_/�����؈���R7iN}�@� �zk �TD:��4�dd�8ѿ�$�s�D�������ᄙL"n�5=���}��}cc{�sP�L@�����=�;8C�(f��~�$b7�кW�Ĺ�J��:�߯7U������Xk�Lf�薽�<v�@��'���T��C+����^]bѿj$nfC�� ����������*-�����cJ��h��!�:0-4("�'Ğ��>D�ɧ5�������XG���1<����2��ac#c��p������Ǵ��xS!�递k,�ac������p�;��7OH�}H�p�{�w?���q�8 � +-E[�G�Nכ�,�����5���|�Tx�H�%���IDAT�-���=C�u���+(-8g�Z�u֯��o� %�7Tg�����@g�(� ��o��0ݒ�s����"���;�p�h���=�����`������54z64�Ǘ#ry�7-���BM��H�u����H�����1&3�ݟ���R)���F��(�~p�$Z=��S� +-Xe̾'Q#VD������uFHLf̓d�~搜 ���A���I4y;Z�IMl��/���H1�ϭ������uG:���o�D�M����7���v�Y��������PP��g��z��l-�\��'G�g3�����o���������q��M��8��S0E#A���էYX���L��C��>�����C�������`agd�����T�h����*[�f������Z���)i��h6�/�w�'˿2��ڣ��{��+�RO��z��������lҊ�|�����Z�^��H�5�4�F����/&"*W�����4�Q������ �����GTZ������?21�Y@1E��H�JD�N�Q�OK3aY����C���9�kY��4����G���)ѐ������KܺބZoll��[�>�ܨlRl +-Q�T�-�w�])��=ž�l��j�X!ֺ;#=J��vŰ���`"6�3�HD�ҬM""����J,Cl.W��e�]᜕�W���R�̽{J����,n)=�Ú�&[�ͺ�ض���<�V�,#_��/��L���M�XF�2ݕעlR�&Ze��Zem]1t��3D����$T�El.U ˒��2z���%���&.�\�TU�bT˦]�J&�M�!�A;o/�K���h)gJfo)�m.[f���JZ)ݭ�ې���A��0E��1�f"����f�"LLF�2��l�`p���[�0l��Rb+�j�X1*��-��X���eX�U��{����������:�f��������Γ��CDcc{�����H���9_�|FJDT�l�*D$����jQƤ*Y�5����)e"��4�rN6���;'"�d(��� +-wm� �Bի���=��9cH�]�M��Y)�{��ʚT!"� C�zgj�WU>�KDd�a�;��PbQ�r*{���!e����*�.�]�Q����EZ_����暩�k"&�������x�a���_i����I�vb��C��NT�z�Ҵ�������x�0���4�h�X��W�C�����C1�����_��'�6�8�x=J�C�}�������l��h�ҍ�?������6B�;�BP�;x ���������M!r+N�t� +-W$oe���6E_f�ϡ�����`m���x��V�J�tRӤ�FZI��vz�������� +-S�����Q-�/������k��N�N��*Yu6�Y����m�����@���_����H�w���w��� +-�Rf��m�/�E����<��1���e��� ��L�?����z������D"�(RъH�bY1���gm��@�mM%��l�����S\�-0�EDJU�_tU;��Nv�WW��9�Y�-���eH�N�o�������$A�̥Bq���yj�[��ll�����*���9����-!�������������V�Qs�����mf�a����������*H�����S}�g'������������B���ԍ��3:%؎�O�x[XwZ-?t�����V��\��V�R�J��/έO'Z��z�"�dNm�,ԑ�n�x�����ց��'�� +-3)"��/Uv쉦�}�T�Ɣ�m6��l�~��������o:��U��P�|p����+�u�@�������X;�?}�X��)"������N���X鿪�O� �������O�\���m,�5I�����O��?Xz���+���R��ep���"'�E��}�ӳJ��7/y�7+i�����������ę�7n��ID�L&��iۚ�s�+���~�1҃!��Z �R����I�՝��qYZkn�W�/������<,���KW�O�*�*�UU�i +-��J��L"�DĬ�~��x�R�v���#9�ip���KFP�D����c��ST�3�e��8�(��|�ՐZ�z^wh�N��:,�;P����/�����ϗ�}:N�T������3��B�R)*e031������J�T.�˕*3ݨ�b�ۨ��q� �D�DnQ�\���(ZffQ\w���\'�y�z���i�邻A�D�X�f6n���U���-I�r�"B��,L�RĚ�Al���&k"S�El�i��XiV���� k!Ebke"�-�0�MVF���L���2Uֶ�J�6�&�("Qd�Ħb6Il�-f"C$��j���U�L۶ �Ԛ�"篈ff"^�/�Ʋ�u�!ݚ u�8r`��E�M�I�l���,��� �2B�dh�V�h!ͬD4�b"�R�� 3�0)��2���VĚ��͊D���D�b�"Ċ��QT�k��i6�lfC�"��Z�T�b2��Z�r]�×�G0��4�1��>eڶ�0Ķ�0��� %�&E��&���I�֢��d�ΘFUHi�B�%DBEY�PVqE$�TՔU\єa�Dlke*"�lb�Mb��f&[�`"fmkfbf[�P�/1��0q�����3�2�"�͓�����������&RBD�I��D�ja"C1 �0i���`&�D��l+"����$!�8�DL�&k"R���"�� &a2����5gY�H�%�$��X�![KF�ڲ�T,�m��e[��$MĬ�H,���`�L�&�lk-D9ek-DĖH�Y�d�Bd�d)۶�R$I�*D$&+!Q�Ddi��Ed0[��W,;cf�49�/3����4�bQ�������f�R�YSU,�L%��E1�Z bf�+"�{��[�0 ird���&%�`��"J�"ֶ�&W�X� +-�����M&R��L�b�2H��/"-�D�r�s���o`')� �ʓ��#�8I�>�����W��[`oݕ��|]�$6� X�r�F��CWo;��,q�'���2�JD(+J3�·��ɣ��jJ��"f�&2H49?�L"�\Z"6�]/4��5�k-L��J��mMDB"Z;�j���i����bD�To���P��Z�́�E����/�Z�A��|8<��ڇ�kI����rr5��i��Y��R��$��LKXHS�{�I����s�Z3Bd�.�a8ohM��$"&K�L�����&"��2-m)e�ئ2�6���",�l�+�֢�fe�z�Z�"b��mW�aj��T��UC��EF�'��K\�=n�X�LֿG�k�������/����QO��vݩ�5{�;���9x���k(��F��n~�Ŷ4+b��U�3�X)-�IkRL�ADd� �cb�[��5��TQ"L� ���r��Z�Rb&�6k%�X9���������2�HHEJ�E,$����aC�&2Z?����������Q�����:�:���#D��6R������VJimʰ���m2 �SIt��E�mͦ����~c!1��b(~���0xQ�2+�Ų S�e��l͆�(�h�a%$�~&[��Tӑ����g��n�{y�g<�O��^`���t�s$D�������TBU�Bl�6�c��3J��.����T�V�l�Y1�)!&�H��"Z�a�aC���� &����b�HqC6Q��U�)i��2�l!�vL�S��,Vbh�"{�LR�fǶg�B�I�������Xkj�i�%����q,6�4��z���'VJ�V�E��&�y-�絘�u�����9��hqG���֖���S���_iW �w�s��] �� ����xS�T+m8�*�2X+[����"�#0�Hj���3̃�����R����{��Du�'��] +-�SVV���旀�%VT�Yb�k�\ ʐ�2h�r��$DBdH�c켫��b�K��f�m��J��l�̊�3�A5���}��s@�Bx���BF����IEND�B`� +\ No newline at end of file ++��� IHDR��,�������y���� pHYs�������+�� �IDATx���w\����'�-�1d;PPq����*WU�{O�:jպ'u[�����uOP�U@Ae�2�u�����^��">ߏ�ro�7�L�r��p��� �������GS���b Tn���>wB!�PY�̕%�)��$����Cs��8��"�ۤ��q$5cF>�O�n�j�4�y�������;!�B�\�,w��+���r���;S�06-����keo�}fw�Z��� |>�sg!�B����k����Q실��F�G06-�p��}�E�� x���*��`�B!T��ytז�R� �I,Oh��4�@Z���� ++�B!�PY�)ʯ�k�:��G�1O�td@B!�B儢`��.&|9��ʂ� �=�ϝ+�B!�PU�/�M�QU�M[�vkV�s�!�B!T��p��23�oRG�E!T,�L&���j5��`�UrE�x<�H��P!T9�4�զ1ϣ���� B�J�eټ�<�R��3�����8�J�R� ++�X,�i�s�!TT[��9N�B����\�@�M�T���}�\ ��Q�ܐ6�>w6BU.2�L�R}�\ ���J�L&�ܹ@en,�:J�BE���ϝ������pd^�BE���ϝ�����W�ڵk,���,�[ss��˗w�С\��h�)e��!�2U�\�Ps���8�"#j14-�Q�"�����-B�J���,8��p�ಆ?f��X�`��mۚ4iR�w�ܙ9s�͛7?�@&L�6mZ�z�������={��+WJ����Y.)+?�n�����)I ++��a�@�M�T*5�POߺz�n>��[��Y͈���"�� ++�x�" ***77W,���>�V�Z%nܮ];sss�HOO��ɉ���ٳ'�W��Y&�ݽ{�Y�fe|}�<==��Ӌ�����������������Z�l��J��״iӦN��q�F�ʈ���ӧ����eMH��}��>�H$2�� ++�"���(���j�R����R�4�U��%�{5����#�!��h4�������0`ܸq��ƹ��W�^�;wn�N�F�U�j �Fs���FS�Z5� �H$�УG�at�3fee��V$��}�/(̨$�ի�q��ɓ'�����G�����~?%!��7�n� :ljj���' ++���xښ�G�����4Ͳ왠#���ŝ��06���Y�%�Kaa�T*������NOO����������ჟ>}�o߾�K��D"����_�v�-[t������r����СC�-[foo���+�5k���ٽ{���MMMU*UAAA�\����B����i�622���զ!a؇�!�P��k�.mՄH$0`�w�}7{�l}}�A����e ++ ++�v��R����[�j%���[QAA��˗��/Қ�S�Nb���N!�J������ʔ)���j��#"(1I˒�>qD(��|�V��(�Z��6a/Jx�gY������'������lܸ1 ���bq^^^���;v�X�V�-ZX[[�Nt"���vvv���w�����Ц�}�vFF���stt4�v��-��t#�2�������Ϟ=<x�����/^�K�.-\���lٲ�;����Íϛ7���>;�BU؋/.^���o�i�˴�b����}}}����m6 ��?������К5k��q�������v�400�֭�v������жm�iWj#�PEjҤ�ƍ�L��q�GD Pb��_���MQǑ8�a ���f���"k�@�R�x<�RI�t������=q��q�����my���666��ɹ����,���q�ر����I�&=x����<y2YX�d���w��sw�����hWWW�fݺu��s��K�,IJJ�8N,k�ᢢ�fϞ��C����͛w��̓�5ǎ�[��ʕ+K<5�BU[@@���ߍ@CC�~���ѣ�-z�[GG�Z�j]�r������,))���������m���͛۷o�6,,L����{�����|�ZUL��*��D�F�!����� D.��I$ժUS��r�\___*�:'(Do�d\n����T*%�P(j���霬��� D�:�={�z��5k�����d�E��D��[�jۼx{{���g�ƍ���3g�lݺ���w|||�ƍ ��r���JKK ++�dWb�8&&fĈ$A�^�~���<cƌ��3��幹�������sssq�q�B>Ԗ��Y�fAAA�~%�Hݾ��!y~��7j�:==�Y�fJ���ի$%�0��-99����������KMM�����x!!!e|V}}*&��BÌ����9s��͛�j��iӶn���n��*!Q)��X�Ѩ�j�� ++E�S�B_bə������E:��vPǩT��>++k����ƍ������ٺu+��[�t�6�}�v@@��ѣ]۪U+''��� �\>z�褤��˗?~�� D.��_�~Ȑ!gΜ�q�Ƒ�#M�6��������/֮]�����V�TE����rwvvNNN��#G��tG@!��H$�accC��@FF�px�������E�(��������&M����FEE�z����������B/""���Oxlذaʔ)۷o��ސKRC�Rq��h(���xj�Z d�[ƾ�_���C$ �B��."ǩU��Ͳ�#���o�u�o�������dbbr���۷o�1",,lժU;v�}���Ǐ���v����������{w����ٳ+V�Н�H"�lڴiذa��{�������;**� >>>vvv����!!��r�7������D"������D�a||||||:u��={�$�|������WXX؋/�judd�3g���Z�hA xyy�F\!Ta"""�Ν�}�vmՇ����u�&M�SʝP�� Q���q�Zmbb"�H�X��n%H�i���Y��"'+K���������2no���izݺu"���ի۷o�6mZ�~����,X�k�.+++�����ٳ� �bee���V�CBBA�������}�֫W�����Ą�G���������Ɏ;F�8d������i��g���L�[ r�ܹy���f���~�駟�����=QB}%\]]�_�����<hڴi�_�y��mѢ�0���گN�:�&&&;vd�aWW������$}}}{{{������ȼ����!TzU�������;wZ�lY�>��q��4��?��c�ggg�����k֬�3gN雉���UJ�F��hH�,��5֯v����o�,"�|�hz _�$_�KUr�R�rrrv���|�rKK˰����|>����}�vCCC�H�m۶gϞ����ݻ�СC�.]JMM�6m�����ɓ�ׯ_�F � O�e7m�T�fMm�S�5�m�faaA>�ٳ��?qc��͛7b�Xۏ�}���ϟ�J��fͲ���駟x<^ff��ѣ۶m;e��PXlG�B_��Ç/\��K�.��M���;|��mۊ������ё���Ǝ�� �ڵr��ƍd�,��{�.i�r��͛7E��(���y<^Æ ����Z|AaƇ-_�|�̙���|���~�aΞ=[�W�����W�����T*���>��S(�� P���) U�l�����Z�y%����Y��45!����"�K�,Q*�M�6�����ٱc�����ӧw����w����$c���<�֭[��T�;bo!!!b���ի˖-�v�ڭ[��������%Izz�6n���OMM������_�r%�`���<p���1c.\8x��!�P�W�V����ϟ?ժUEf����_�`A�֭Iه�4]�~����G��h��ѣGzzzu��!�V�^���://������� M�6���d��G������B_�:�G���_����9��H�[�ZU���A ��%���P��'�k �җ�=R�q%e�����4��2GY�>!>>>]�t��ȨY���������9s���4����l�"�����W�X���jmmͲ,�$&&jk0�@�R��#GbccϞ=�|��u�ֹ��zxx|��woϖ�[�p�W�lmm۵kױc�6m�DGG��S��.]���@``��5k�&;v$�t��=55�$ɜ9sF�9eʔ�_h�BŲQ�:4x�`__ߦM��Q��߿�СV�Zݼy322R;L�0ӪU��ׯ�;w���u��AW���&''?���Ņ<�8�KOO�Ⅳ����'N���B��(�Ji��i<�0#�8�PH�ٙ��;�l8[��e@AӤ�M�è�%��U�n����iӦM�2�nݺdeXXخ]�6od��hР���Stttpp�s�nܸ�;�_�eff֮];�������H ����D"CCC�j�6m�0�~�z��ׯIO�F�@__��� ))�cǎoIOO�9sfxx��ӧI�m۶9::��믶��Ç/��E!TeQ���۬Y��G�H$cc�M�nݺ�F�����-Z�t�q�R��J�dY&�egg'%%���juttt���I��Ǐ'&&���X[[���Y�7nlnn~�����\www2�#B}YJ�sQ�o`�V�x<�@ E �B�Je�"�e�+W���٩T*�P*�*�J�T ++�B���N�+))��ϯC���=������33f̘]�v5n�����˖-����ի36o����R�N��m�#��^�~]ʳ}��:$$��˗��͋����������ɓ';88�9u�6111177��ׯV����!��Z���+vFBWWץK����d��ׯ�"�K�.�D"ss�mۚ�����%''?x���ɩf͚*��������֭[�_�600�V�������ƪ�jBB_��\bCCۗ/�5 ˲4M+ ++�\. ++��ݎ��L��PpG�өT*�ek��620�����ƌ���1{�섄�;p�@�Z=eʔ�� �ŋ����D��ӧ���nڴ��i===OOOooo���=z��Q2�y�.]���M�ĉ䣷���)S�}���q�N�Z�z�֭[�|�,������ؐ'N� �k����;!�z���k�ͱ���{��E��w�ۤ�z��3�k@mڴ)�##��͛�q�B�����wrto�:&�))h�J�,˒�uN�J�v�Ԋ�,�R��j�J��h4-[������=�������ښa��۷���u��Q;���mnnnnn���DVN�>���R;,�ƍ���������e���?|�"�ܿ�����%++kϞ=͚5���۾};�XYY͞=������X����q�BUEQ�l�7��Q�>0'B�3�2s��X����ܸq��0|>��i��y<˲�?6�I��!M{��пoE���-??��i�RYd�tT��!�y���J1�B�������d ++u� I{t�Q��רq'<<##�����i>�O�Odu�e k�Vo٪U�v�{t�V���xFFFd#�*�H$� U EPFU%ׄ"#DFe�y�P(8� ++�H=�P(�0�psk�V����*'�DR������!T����!�B��X�����8}��X,�^7UB�j��B�+DӴ���L&���j����/EQ<O$�`�Uf� �z/===|�C!T氎!�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B���3�B_�'�ܱ���T.��Sj>wn���i����ϝ������s٢(��i�@```���?wv*� ++B�_S�O�3�l)�c}��3}hh�����-�ϝ�*���P �'A�q�F���d2�L,|�!T֨R!��;�0��D���@z>���W��q-5���;GUFO�9�@B%���X����>!ѯ)�@��a9�y��~M}� T{��!T����;�5�� $� ��I��X�����a*�\B��T*?w*{%� ���o��<��B��*� !T*,� �QT�b��b����,� !T�!TJ�e� ++*!��$�D�B!�BE`S�B!�PE�0A!�BU$����h}���B_ � A�*gxc:h���8D����=(k=pS��LŤ�_�����8����?~�xVV�ڵk_�~��ŋ"/�Ϟ=۸q�Z�&���uh4���p�V������j�:000++��A#""T*U�I�Up���֯_��];|�p����������;w�DDD���Ǐ�_�^d+�Lv�֭��삂�"�W����7����/��қ��������WܲK���E�5��DZ鲷wd���K���6t|&w��n� ͨΎԞ������"�O!��T�S�q����gE˕��d�ۿ����:�57� �`Aձ�Dx��um���H�f�V@Cc��,u,�1������ G&e�ԃ���=�N~�`d�ޜZx����edd<}�4&&&<<<!!�������̙3�;w^�h��ѣ�����_�|��������eٓ'ON�4Iwo���߿O�>�����\�s��.]�����;w�lٲZ�j�����������4m�4++k��պ��ݻ�ԩS�rXXXnnn���KyF�fѢEs���şpa�^xx��ӧ���\]] t����fY��Çw�Ё��D�-[��;w�$�1cF�^����Ϝ9�a�sss�x���0���qqq����������u�ڵ����7o23iҤ'N<{�L�p��G���@��,^�x��ٟx���������?RT� ��?�q���Í>���T�4?{1��ч3��=����c���U���tJ�\�:4�a������N��%ekJ*@͂oFw? ++5xnU���!�P�d�'�����ݍ7����Bt���~�w������m�5� ���<�(P�ZÅ���,��75�z0W���.� ���}p��Ö�E"��1�u>~�U%UC�j�[mz�u �ܜ�g��h�]��tnx[�z�&�R� ++�i�&WWל���ӧ���S�P�����ҥK�O�������R����<yҰa���l�H������ndd����Ø��W�VmŊ&L����^�zvv6�������@FF������ ��wvv~�捫��q��ܹ���f����� my?˲��0a�����߿?44�aÆ�F�"�����ѣH$�>}�t�֍a�5j\�r�����^�^�Z�b�̙3/]��jժ� ++�B���/~��Y0`���7��O����>y�d+++��ׯ_JJʪU��͛'������III���),,LII111�D"��M�6/^<z�����'6o�ܨQ#����]�v��{ ++�B7ٹsg`````����F�9}���k�233�u�ַo_��m-�����=���Ԯ]���[XX<�<66�^�z�~)�2Pe�XRI����X�rA_P|y�L~�w������ ���JL����|03���R�pr5d�q����n��ل�m�w�R��������2��!���߯k�_���Rh ++ ����˹k��t�� ˶��&X}����i���NT�pE��4�r��S�1����̇jB`h�+��;�� ���%drÛ1�oT�ʐv��yzzR5v�X+++�a�˱R�lڴ�#�^���⒐�0z�h�����'N�����ӧO'+���N�:����K�,������%_ikK�͛gmm}���f͚@\\\��{��Z�vqqaYv�ڵ�`ɒ%ϟ?�0aB@@�X,NII�={���������ˍ��۴iӥK��s�v��U$����()))���������nӦ͔)S6m�4c�R������^�x���SXX؞={�z�j333�R�P(�6m ++�4MO�0�ʕ+�o�^�n���?�$���K�.m߾}���I����8�;r���"�>}��5p�@�a���)�8p �ܻwoѢEӧO?/j(�� �IDAT��� y��e�ƍ���w�ĉ����C�KV�AȻ�E��=o�Q��r��GN�^�Ús�:�(�N��5�=\��4�XS���Gԗ�ˉܘ�t��� ++�E}�^fs�܋<�Z�����C � L)�~���� ++��5�b=��.���.ʧ!t��J�Q��(O���c:��{q�7�+�2,��;��-�5g��`�O@��J� ++�.=e���Ƨ����˓����P(�������@(&''����oߞ��T*�033;q���ٳ�������˗/��������E�i�٪U+� %�}��=q℡����מ={���`���/^$�8���ѡC�z��M._����M�tZZZhh������P�~����_�p�o߾�/_����ܹ3�:����mڴ������y��a˖-+�~����p�BOO��Ç�����ի�Ν�p��Y�fYXX��M�aaaNNN������Ҷk�w�^�=�є��i�֣G�]�v13r��������������b�ɕ�2eʻKLL���!!�(��7���k7�۷/i9֣G����k���,��ٳgʔ)^^^�ШQ#�U�իW�?��̬\�#B_�rB������6� 7:=�_+mAו$��ߣX��8�4B�+�=�ˋLdW�����=C���ƿ���O�E)��B�ʰSK��:�~#�Z�T=*F�y�Q�"�e�/��j�����(��σ@���#�ը��2�"�����|�0�?%=�����Su�E�xp��ԜZ����v��&-m(������>���.�b!���m�������y&g�O9S�r+��HG��v������˵�,�Ձ�������G�JE^Usrr�J%������� 5~��#FL�:�m۶?������ny<���|�`Y6<<�S�N� ���@ە�aÆ��������mے��ׯW(B�����ٳg�7�J�ǎۻw�����������zCC�E�͚5k̘1���sss��ζ��<x𠗗ׅ~�����L�`Y�����5k��T*m��ZS�Z�j�~���m۶YYY��|���/������✜��-�N�8!�����AIF�B��͛7O�>���U*�Z�&b� �-,,^�|�ABDy!-jQ�\h2[v��u��ՠ5��A�V~�b �6�� Kƽ�o��Hͥg�dO�ڄZxR�-����J�(C��!`��Rr9I!��Hm��Jк#�ՠ��so�oS��~���K�+;3�&cj�o���tΣ�b��9��6�5Q� ++N�P�@�����.M���\*��[xZ� 'j�P ++����{/�ϹB%7�5��'3��Z��8 ����,�\���?~����`�ر#F�hݺ5�,_��^�z}��]����e\\˲��d2������r��)S�����T*CCC�عs'�K���oaaA��JOO'��B���ҲZ�jIII����_����,,,�]F�R�,[XX���I^jmmm���/]�ԫW������@kkk�HJJ"����$77����������t��իWaaa8|����|+��w�~��33�1cƐ����s�:99��۫T*�H�����⒔�4r�H�pww�?~aa�D" ++��}B������lll�@�V�;ԘB������ȨQ�Y����={��ܹS���8�֭[����M/\�(�J���;n�84֭[����ew����W�����(oz�m͘VLD"��mMucJVR�7���W��AYxX�n���<�U>dH�fM�D*N��N&���r��t�!TY (���!*�kQ�f#L�ي�z���h�T���"> ����Y�����m��/�ο���4b��6� 7�=�'�����GcJ�����H�·cd�ʇɧ�B(5����֤N�s�e�P��Uɋ�T*Ubbb^^^�����Ҳ��-Z�i�&KKK��H$ڮ�'Nl߾�Ç�nݺ`��RI�(~�����w��2�L�'d�ĉday�@:=_�r�nݺ���;w�j ]Ǐ'��&&&� �/^�t��ݻw7nܸY�fd��w�c"k����[W��4h�s�N��I��#F�5j����T*�Ͽv�ڻ��Z�J(Κ5k�ԩ���]�z��ٳg/\��m�6��������~��M�4);;�t�1cƸq�)�|}}nj���O�����M�6�=���^w`����������� iX�=z�haa�I��t������r��J�+I����+q����d�17�٧�ӌ�0+Cٕ�����,��ؘP����x���'��mͦv`CZ$��Xً����,�����Q��\!T���rp?����3�CR6�hEu�I��:��~u:�w��i���AK��p�87;��6U� ++��R��Z��ow��oK7��Ͻ ��� 1����Z�QqÐ$�r�`iHp�<��*c"�J���_�~M�u������988x���^^^NNN$�n��fĈ#G��u�R�466�ݭ���k�Ο?���U�V)�J�>!���gΜ���All��ŋmll�j���~�M�999� ����6lx��ႂ�X�u�VRf_�fMm3'R�B�z��dږB�M�d`1�Q�V���VUE����:�.�X�Bw��۷�{{�����͛k��߿����?��t�҆ �� �8n������;v��ĉɈ�����S�� ++��=~�822222R{Ё����;v����+V̙3�Ģ�b��144l۶��G�HRPPPlE ++B_����a��;,�,�K�$�c�.>�՝��%�x�W%�n�;Cؒy��ֱ��r��)ܘ*�8<��0�m���x 9�ˑMC���4�πO�I2#�O�@s#��A��jF���0�O=y�Ш�ÕY��ەy��-��92�G ++�����t:7��R �������Xו1��?5�Г:1��j� G��D�%����^s2 �@CK ++��8��kL�dU���6l�p�ҥڵk+�ʱc�v���������O�>�H$۷ogY����ohh8a��##�w'��J�����qܺu�ƍG�M�:������z��q�ƛ6m200�i:''��sGӴX,V(�.]"!S�F��<yB�߬Y32�WFFF%霠;��hgD!�i�{xxh�F��t�P�^���d� �nܸ�q���s��ݽ{��ӧ+V�8v�Xǎ�n��XnÆ nnn���/_��''��������s��]�v-�sZZ� ���;� �d���(!!�A�� �HH�8r���B*�c:����[?4c�ӹ�wƏ���$es�8;j�iM�z��<��Ct��U��UƢ5�*C�ͨ9� Wg��9#a�����s�6���SC�Zw+���20BX���}�͝��\M������Y�jM��E���߯�<%��L�\i17X�n�א=�O������|���*�J4+S���t\:���� �5��ue�]:t̘1VVVcǎ�S����1�qdΊQ�F�!��աC����ۧ�*-�JU*�B�عs'˲�o�EQ�{��Сy�i�gϞ^^^j��o߾����k�&a�@ S�Z�^�fM�-lmmCBB�֭ۤI��ԩӰaÚ7onaaq����3g������������u��ն�z�9����>��teff���'%%խ[���H$2���:�p�BR�����qҤI�ѴHӬs�����N�6 ��<S�N����@�㟌�[�F �X���0w�\}}}OOϘ�����233>|��;Ə���z���M�6�˲���vvv�z��*�8�*9k��K�����ɇ" "*O��hE7�A-.������yu ++��,����L��`YO&6�;x��Ă��HC���hI%f���-���^bPZ"�N��{�lOsD~�]��HM�<�����t+U��Wo���9L<�֦L(��l�m��kn� ͤ�t/7Z_@=Jb�\Ր�"MkP��9i�ҰV�Z��r����?iӨ��N�:���լY���$;;[Qh�y�O�<�ѣ����͟?�A��W�n۶��i�h��8N��L�6M��$&&�qc��������j5���b� ������������x�|�MpppBB���'�3����nذa߾}999�G�nӦ ��T��w�2��.[ٓ�ddD,]�=ڴiS���[�jE�� ++ ++���0`@˖-I�GGG�X����P(�ԩӢE���(�"�S___(�^[GGǬ����T[[�b���o�����Ο������izݺuzzz˖-�_�>��z���ܼf͚e|]�b�qr6�u���̧����_Q)ܕ�ŏ�e�������ژ6�g��ǯ9> "nƱy2hW�R�p�o�H��*ȕp���@��?�B� ++���V�������; �oM}[�g��Ǖ�������� �, �X��PW�v�f�,���1��}4B�n�����~�E�����~-��l|7��`(hS��y�2�T�,˾z���(�\.�J'O���h6o�lff6t�P77��ϟ���J�R�X�k�.�)J�~���}�X�MNN�3g����M�<999��ɓ3g�$��ڶm������իW�,Y��H�c��w�S�N� ���555mժU��}5j�~�z�5�=rss�/�C�IJJ�]�p�Bݏs���֭����������o�Y�x1Y~���{w��ekk{�ʕ?���?�(����Cwle��ݻ�6 ��c��`�|��n�V�zum�M�]i�4�����㣻��͛������ ��*� $G ++~!�Z�56Շ��z<�К��B�t-���������Xmm�u��=ms�� �?+� !��D5!�ʸ�O��5�� #e(�����%�,hXhds��,<O�tj6&pɹܥ�����m���;�� �0�&T�~-����N��K?/�xh��T����䈦��۷?y�Q�F-Z����vpp �y/^�e�www[[���ܹs�i/ԨQ�=z�,۸qc2��СC���(��Y���ɓǏ/�J�xJ<��� mq��y����t�8��Ĥo߾ׯ_�o��pw��!m0�ymذ��E��U�6i�$�d){��111���ם�v��۷o'5W^^^�;w��充�j���i�������@ ؽ{���)ֵk�ѣG��Ӈ\�&�HN�<�o߾O� BU����GF�/�7�>>d��B/���W_�?.�˸��[P7R�>��4�ꃹ>ţA�� ++U�k�¼nu����+�wF�����3���qe���~��/��0S��O���q�!��+�AY�@:բ�s��!�7���!4�샐�i|2�yՖ���P(lllJ��e���� �;z�DZ�����966���A7�� ++�"!!A;��G(���/�L�)� !���U�A*�W�|vU;�$0AU�L�)~TA�B!�*'� �B!�*!!���,B�GY��A�R� !�>�j�V�*2�BUL ?k,�C�B��-!�Rޙ��/_ A�\�>M5� !T�~M�'uE!�000��Y@���4�*� ��B�Ś�Ҏ�8!�ab��YGUR O@������`�P��һ��֣m�6\DiQ�0������9V�������}��w�1��Ö�T����)�RӯQ ANV�B!�U�)5%!��� ++~B?ɠ����TL�ЗJ�@5}p�b}\���%�� �B}UJ� T~0A!���Ȕy!�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(BB!�B ++��B!�P�� !�B!T�0A!�BU(^E����������^^^�| evv�R�$�&&&j�Z7���EQڏ<�x����ӅBay�!�B!TV�8)((��_�ׯ?lذ���ݻw�9sF__�ʕϟ?߲eK�V�����<y���������!!!d���~ۿ�͛7uܽ{��{�y�D�hѢ�͛+�Jm��FFFe{v!�B�OW�A��͛�b����CCC�v�|���!C�4j�h�����ՓH$���������v�f͚Ν;6�|ܸqc�� ..�_�~�d2�lժU))))))'O�Ԯ ++�!!!���e{�!�B�OT�AHݺuw�ޝ��oee�{��5k@������Z�lI�4�����;v���۶m��v��h�R�T*ծy���+?~ܩS�e˖�D"�������[�d F !�BUBe���ׯY�f+W�l֬�@�֭[�&�߿��#G^�xaoo��]͙3���R����V����8�۵kW�F�֯_�k�cǎ3&,,,<<|ժU͛7/�SC!�B����noo��?�9�[�nժU+6MVVV~~�J���~�̙���9s�L�1;;;77700�|dY���K��������ի;vl�ԩ�п�B���`bbbddD�_B!�B�D��������w�my�����u��E����*�?��c߾}pvv~�4�������v��_~�E7���%ɲe�222�ի]�e˖YYY1s�#G�<}�4++�_~�ѣGy�#B!�B����&L�իWXXXhh�S��Ν���w�^;;��{�~�WzaaaNNNjj�B� k���[�eׯ_���ڻw�u�r�c�kkk���ٳ6lػwo� � ++�����t�!�B��S^A�X,�0a)S��� KK����GFF.X��u�ֺS|���p�ʕ�k<==W�Z��͛���o������K�.�M���]iS�v���B!�Be���קO��u�m���Ɔa��#G._��M�6%F ����O��ƍ�5������?v�X@@@�����.]�\�x��ŋ����ݻ/����� A�ꉉ���Y�D�j�«���.���j�^�rU�����;w�ƍu�- �F����w;��������8�U�Vd�����������;w�������G���SSӲ9�B!�P�)ߑ��7oޤI�]�v�_[�y�F�R���Y�T*�B�H$����o߾�e˖�3gj�X^�~ �8OB�_8�S�՟;}8���Y@�FC�����3f;v��U���W�M�<y���ߪ����d�LFB��w�N�6m��zzz���KOO�8�ŋ���3f�X�j����\.��Ζ�����kѢ���^������u������ԩS�?.�833�ܹsJ�R�_���ER���Ϛ5+22�}Ǖ���ׯ��Ϗ���駟�i�z��E����D"ٲe�F���\>�|RXS��Ǐ۶m[콺�����@wMFFƜ9sd2Y9�����8p�eY�1;;{�ԩ����K/�H��A6W(�H~~>I�U��I��9sss3�#�H*�*Fjj�+W��eٱc�>|��sg�egg0��{�VBB�������*ٷo߃� 66v˖-d��,�ݻwO.����3&++��]EGG�Z�J{���x��������j����/����^�r�� ++ ++:t萘�8f̘ƍ;::��Ç�ϟ���SXX�u��;w�4j�hĈ={�<v����=z�d2{{�w�:DU�F�9x�P(\�z5������5j888\�x�cǎ�5�����ׯGFF^�z�N�:�L�<Yw?������ڏd�.�92--���D��_rr�+�_�.�����ѣ��\mE�q�����CFFF������СC,XPd�X,>z��!C������ÿ�Jk�Ν6l ˳g�1bĭ[��ׯߩS������(������=Z��E�d�{��ڝ�߿?&&f�ڵB��������̓'OΘ1C�V�4m``��������ݸq��ʪ,O������={���@�R�?���O��СCK�,!��۷��dw��-��;w��?~���dM�6m������})��� T�'� ��ιz�ꠠ�w�իW�5k֔�9}<�e�ׯ��4QQQ�X3,,��?��ر#Yy�ƍ�S�fdd��@ �������ldd$)Sj9k�� �IDAT�x�{��%$$���WX�*�D�~�����ׯ/\�0q��իW7n�x����d������gϞ��7n�x_���ӧU*M��ڵӍ����oݺ���hR�K9�ϥK�>n�^�z��oݺEȒ022����� 7PBOO/,,�eY�a�-�k�0�ʕ+G��s�������r�B������XPP������hcc#�W�N�tjj����� �< #8GEEM�2E�O�����ݻw@���k֬y��Y>�oaa1hР-ZDFFΚ5�"""Ο?�;�ͯ��ڵk� ++���Ç���H��{���o�j���� ���@jS�rݺuO�81l�0���Ғa�\��b��#2�q�ƫV�ڿ�J�����ҥK@@@Æ O�<��흝����'�Iz�ÇϜ9�E�?���0���n叏�ϨQ��/_Nްccc��:�@�.]6m�D�>|833s�ڵ�w�֝.�������/�ӧO���8�366~7A���۷o?hР�6i�d֬Y���oժ�����'D"�n�5hР��944tϞ=dͩS�����aL�UwN(.�ڷo�ӧO+��>گ��J������'�I���cǎ%i4��1i�$��X�%�}��%����\�pA |�3(3����R|�G�ꕶ��a�ڵk?x����wg~۳gO�EU��˗mllHܮ�h�|>M�+W��ݻ������'I���c��HJJ�������Ԕ����w�СÇ��#GBBB>|�`���G�feeU��x����r��w��h��)ҿ*b�x�ڵ�������N[�}���u��]�|������>44�ܹs�yH�ҭ[�9r�������{��<y2�� �¶m�J�R�~���r�ܹ�Ǐ ��Ν;�5J;v�,������ ++�F�u���ss�m�~���3����ݻ�,k��K�{�����sss]\\LLL����e7ښ��7Μ9sܸq��q����+V�X�r�ɓ'� V�E���ͮ]�8 ����WRRR߾}�^�J ++A�A���mzz���9 ������r�����X5 0`�ĉ��f�������|>��Ғ� ++�L&cYV.�i�GZd��XD~~�D"эu+���s�UwMyd�<���֨Q���i�f���NNNO�<Y�x�U��in�V�=<<�]����|���aÆ͟?_�R�=�����D *����/;;{ǎe27����T�>\����R�^�s�����-[����������3SɩT�����'55����T*Ubb"�6,///77��w\�xQ�Tv�֍l��iK-CBB:u�T�z�iӦ���/"���,_�zE*ߪ�*W�� yR�m�vŊ��g�n�ԩS;v�����Ǐ�>_���Ǐ�nnn�=�1����ʲ�ܹscbb6lHQ�\.�駟\]]�C�;wnڴiڽ�СC5jt��%�P�V����LLL*���RSS�R))�KOO ++��O���w�t[s���P���ő���ǧiӦӦMff����URHH��Y��,��Z�bY>s���ٳISX��8q�ÇG��=���x�ܹZ�jݸq���<..����E ++G�̙C�-��~������ؐ�gg��Y��e˖mٲ��Hޥ-�/D^��ׯOJ7��� 6,�S([eu��Z�~�����W�^�{e$((����~���>t�P�Νe2i�M��� 6̘1#44tyR�tÆ 6lhҤɣG��BaϞ=+>�*�j���,���{��D�����B�E�)DĂ�"vEO,'�X���YO��v�ۉ {G���"��Dz'$�����z� ������$����8���ygfʔ����H=dϞ=�������:`����������7n�>�ߴiS���͛�M�fll�8bB����4 ++}ֱcǞ?ޯ_�����*�^�v�#����^�z��-3336f�rTj^^�Ν;7m�t�����R �@���%�"""fΜY/#�q%Sb��}����^"���5`��{{�ݻw'$$����oX쉭�����ݣG����_~�����'N������۷o���w�=nݺ��痖��cǎ�����鱭"�ׯ_��'J���M�Z�vY��K|ay�n!�<x�bŊ={����4�ƍ����ϟ߶m������g�~��߿�~�zSSS�+V�;��A�x��G�V�Z���>�c���75222$$��������֭�0k֬iҤ A�/�ӧOW�X��c�<OCC�Nr���^v��G��&�ܹ���φVu�m=z4���S�X������� <<<�����f͚���m۶}��Aݪ�+'kݺu�2�ҥ�ҥKI�lѢE�>}�,Yү_?�~bG�y����3� �I�&M�4��Ԝ:u���ޕ+Wj��������={������k������p8����Ǐ#""V�X oIf͟?�ԩ5uߧ��d�J6`�����ѣG���g̘�����igΜ�0a���Y5{;|�pqq�����9{�,I�%%%b�811���|Ȑ!���W�^�g3���%L����:88888�={6333--���<77W1����TKK���8**������W��@�� ����ܹ��Ç�;֯_?�w��!�Yk444���"""����<y2k֬�����D� ">>�ѣG�� �"6`&22299����ի�����ɋ/V\S ���g�[�����<|�^�x�g�ww��������nܸ����&&&���Ӛ��|>_(q����������Q���<���@CC���;99���!�233>|8{��������ׯ_���O�[R�DihhH��D"��ܠi��������TXX���k�C�{�EDD�@�.]nݺհa�]�v�������a����@OW�\i���;>�|� �ڵ;u�TJJʰa�Z�ly�ܹ:J����3..���Tq�{ӨQ��K�n۶�w�z��ҥ��Ç[�n-_�o߾G�qrrrwwwpp���;w���ŋ ����jժ����Ԉ��.���rw�ޭ��2e��ѲFDGG�d2�S\�`���������{�����ҥ���ͨQ�j��[O�>e�岳�MLL�ϟ��&�����훒������� ++�iii) ++�g���6l�ԩSق��ݻ�g�6jԈm�255�g5�-!�R�駟~�駵k���e��ܹ��{M6�y]���bC6-ZԴi���� ++� ++`#��͛7���������ǧ������Ͽcbb�P��˗���DGG����{�Э[��w�6�V2��������˅B�<�z�-ߧk�������+�`��]�t���}���!CfΜ���JKK�L�2x�`6�l�̙|>�ҥKS�L),,d7� ++k���^^^\.7==��(777��o�H$l��"����%����7n �(�y�榦�l���M�._�|�ҥl�����'��}� ��w}���s�P(�9sfÆ W�Z������;nܸ{���u���Y5{�dkn��d�kk�*�����ː!Cv�ء��K�ԩSϝ;�Xۼy���]�vnݺ�e˖�֭�ի�P( ++ ++������Rlz�����JKK��=���xS�N=y�d�Fnn�c�fϞ�o�>�ѣG�?��d+W�����۷�|aII���G�-�/_^���̠A����8(ܫW��>�+4!����������������gϞݴiӲe��Ν���s�D���cgg��ϟWhX�p%�'����>�������P�l.--e�����jժU�|}}`�ܹ={���[���GDD����� ��u���� ++ mܸ1�0:thyy���IFFƋ/�5k�nծ]�e˖�[��S!��7�v���0�� ����c��]�~���.���>�����R�մ���!�3g�8p��ŋ=<<LLL�|���[�~��@SSs���������Y(N�<��(>�_9YSSs�Νcƌ9q�Daa�D"a����|�~�U�V�䂂�?~��S�);v<r䈶���ի߾};|�p�D 4!T��p��Q��H$m۶�p႕�������͛7����[���� 6<y�����-Z4a�={�Jʾ��_9���L(��ƺ��V���x<e�MKK���ڻw���[RR��;w��`��bbbfϞ- ++Ǐ������)�2�=z�P@�[?~|��R555��~=�T�iӦf͚yyyu��������D>>��#G"""��ļ�<v4����W�^mܸQ$�D">��,���M�Q����"""��NE�����P(v�Ё�v�ʕ���+���>ػw�#D"QNN�ڵk���mllN�:u���o��چ+!X=�:qÅ�k�;����Ν;w��-&&���'>>^�'�ʕ+�A���b�8::z���������c�届���t�¾�{�n~~��Q�BBB~���˗/���S���Roaa��ӌU"���v���B�p�С���777�ӧO˧�c'�366�����������5d���4�X[[�$������ڴis��]==���t��B�v�:u����DFF���).ٺu�c�������xlݺ�����ή�����:::u5=��dO�0���_q�w��(���!���_�U�D������O�<Y�z5��K�.�<!�������PXX?mڴ�s�~�DՈ��r�u����DR!����}:j�իWǏ/ ++O�>�|��[�v�֍����|�����֪��l��s�α�������z3$Inn�ܹs���?���bgg�bŊ_�����lmm�=��V� ++ �o+�����A������(>�*))����)))\.��+vR����#F����nݺ���ѣGVVVC�=~���i�?5��RÕL�1SPP���w���������W^��������˗�@�d۶m###`�ҥ����7ZZZ:::�D�?oHMM�3g|���r��1�묪����mJJ ++��ԉ7o���۳Wy6h��Ą}���'��ٳg666�0�*5o��K��w��А �X�Ίu��%oo�U�V����?~���K�.�ѣ�|`���ȇ���mڴ��������Ʀ�0����ϟ?'b�������۷9r���ܹs�����x�֭�� ++ ++�(�#G�T9�mjj�kײ��V�X�����d�����cg����300�����������ݻw��v�XYYm���l��ɵ���_ ^9ٕ{��]��k֬Y�L}Ϟ<y�gϞ.Pu���77���By?��={���!��͛۷o���f�������}��m`` ��F�����s��� ����+?���4�g�///�`���@+++6� ++!t�ԩ &T�x�����:t�˗/�o�hddԧO���y�ҥ�D��1Sb"�h��>|8s�̓'O�-[fll�0�T*uqqiذajjjzz�����#X.������������2��ӫ0 ++~�.ˊ��]\\��_1nܸ ++7j��ފh�6���)��| ++�1��w[My��yyy9r$&&�СCVVVb�8888,,���7l����.\XXx��Ev>�}�����Ι3��۷'Nd{�����Y%���qqq���� ��������9s&<<|ܸqqqq���|�k�PXX�ٳg,Xp��m___����!�ZUU������BMM���@��SWW����������H�+�"�a=zԤI��H�W[�z��Y�,,,���O�8�z�jUUU//��]��+dgg�<yr̘1...���l�b~~~^^^^^۸Zo8;;�9sF�QI�˗/W�St�ȑ�/_��AUTT�1eee��P�s��{��ɣ�H��c���������8q��!C�deem۶-??���ϟ?���k����������`J,44455����R�488��߿r��ҥK{����)��L�8Q>��է�Tqd$� ~�����>�7+?��ߧ'O�$$$���).D���QUPP�F����_�~��d�ի�<|��f��7��W�6n�x�ҥ&&&�n�jѢERRRrr�5k�@~��>ח��u��u���&L��� ݺu���;f�_�լY3v�)S�8p�B��D"������z��mfff6FFF.Z������������ɓgΜ���c�Xs��3f̸q�8�0&9��c�5���:u�ԩS��@�#DY�|y-$�?�vWN�(.. ++�jjj�?.((���߃���������ĉ�[�������$IR%������̌ �R��S�Q�P��bv�>T��Q(�#=Կ�,>� ���߿?�D�w��lܚ���I���㽽�uuu���kdd�nҺuk___�"���9mڴ����m�.[��iӦ{��HNNf;ey{{���>��ϯG�u���+!�svv���a�8N�2eҤIeee��a���p�\��y�������������+�Jq��-Z���(�����Ξ=�SC!�4��榥�U���eϞ=���Q����&Ir�֭!!!����<����'O�����<|?����!,X�v�Z��=z$�z��ADjjjFFF�6mP�~ؓ�aÆ�ԩ�ѣGmll����F���fΜ)�ɲ��*TBTTT~�����xMMs��a�##��#GN�2�����՝2e��ɓsrrJKK��5j$."IRqE�͙�����>hР��X��ѕ�}W�ѕ�%��fF___e�6[___~������6v�Xmm�Y�fq��!C�({HQ�СC}}}ٳ **�իWur䵃��A��z���O]]}����,2�����]]]����cQL�0aȐ!"�H[[[SSSWWw�ܹ�V�jܸqdddff&����ikk����������ӟ={�aÆA��q�������џ�/*��,��|�AՠiZ&��!�jߋ/�y�*�J��n�v��������!$��(�����s�6�an0#��8��s�U����<¯>7$ EQE��!}��U��Ih��a��F���u���7���������E�d�O�5�A�r��aJ ��`uLI[B0�0ð�F$�q��0�0ðZ�+!�a�a��*\ �0�0�0�V�J�a�a�a� ++WB0�0�0�U��a�a�aX��0�0�j��`�a�aV����(ʞ�1@ĥ��t&G�R��� �0�0�b��`kFښ$B-L4p%S��E�M��ݡ3�HUP��C�0�0þ\�n�@F9�ڋz�>��/*�ԇ�,�M��V)>���u�ȿ�J;)��0�0����S�B%�~�4 ����˗/��ͭ�ZRRR���KJJj���o.6��a�aX=�� �?�o�n������?z�a�B�$;u�v�Z�j�=x��]���>>>QQQ-[�tpp���}������|����Ϝ9S��w���''� 6�d�����A���0�0� �?0ߪ%d�ʕM�6�{�n�����&M��\���mnj`ii��⒟�߯_�'N���\�|yРA������6mz�Νnݺ͚5����w��Y�p�7JV'ru}�a�aX �|�!z�������Ν�0̒%Kz��ٳg�%K����y���������[YYikk?x�������/::�������w�vrr ++����p455W�X���|��MMM��-҅�<�a�aX�!e���QQQ666\.w���:::W�^�={��[�nݺu666111}���fo߾mӦ �������,X� ((���}����������+W؊ �t�Ё}q�� ???�uHH�������H#V�����0�0��7�'$**�����߿�����g�vvv�.]�T_ AEEE=~�xݺu۶m{��݀nݺոq�˗/oܸqǎcǎ�۷ohh�-[���nj�v��ѣG�h���^��d��$R|�SH'Sqg3��:�B!��^AB9edL:��<�/�a�aX]�&�����1c��@���w����� �{���;�t������_�|����m۶EFF���;v���^^^Ç766�(����ӦM��xyyyaaa���kժՂ���kmm�Fd����� �IDATU��S.�TA4U��J�Yq���fgH��I��r��$ �0\�ACg���>�,+��p�a�a�R�WBy#�J---���߰a������Ջ�{�lٲ��(??___��=�������:��]�~=�:�S�N���F������x�`ƌ������AL�6MMM��ի3f�(**Z�xq�' �> �,L�u<��UMMMUUUu]].����JA�H$�X,���S�o�ԫ��0��G�V]�0�0ðo��+!���vvvA����ƚ5k*�@D�Ν>|8p��*����-o����rrrZ�|��?�lll����b�;_�x����X,fW1b�H$����(���#�����O���7,�=�y�����*�����QQQ�r9**E�M�B4�0$I3�ͫ�̛Y�3��$G���oc�lNn��0�`QO�H�b�uP�j0�3��#����g�m���!��a�}��X�D���d|\2����~�A��*��!�SUF�5ߤ-�)^%�����>U 4hЇ��Z�jEDbb"�dz��~������Z�l �mڴ�իק�%,,LqFL�}��Z���_�T��*� @@�!��H�D"B&�ɤ2@�Ќ ++GE��z����m�di%�G3RW�`�i�����$�RrʠP�PPmMɁ�љh�3�Y�#� ++P���a�(��yٳ���j&�P&�bi]G����|)�`Z�|~e�a�3��k�.�B4��v�F\m�"!��L���\ ��ݣc���51�Ua'y�h�YZ��Z������o߾�u���|||>�i� �(//��d�p�ڵ�S��_��ҥK�.]�>}��ի�v���w����G�EDD�Y����gذamڴ�߿ͦ�>�Pe�����UTTh��i�$ ���%�a�ٷAd�Oա�_��<hۈ<��"1�3I0� 5� ��������Oe:�g^ࡼ���ᜨ���H����Å��I#2��q�~�� ++�é���&��j�ѕ*��+t?sb������B=d�&��ބH�GJw_U}n�@[}�ڃ2�"^f2~L��`�=ioAf�-��e�����w'j�i��u;4���9����~�&z� ���yh��e���fu!�4'D8�\y��@���Ds��1��,M��q�g��*����F�[�9�2�$�N� ++>F�������(:��S��c?ނ�$�Q�N�ӑ��=��O5m�1���?���:���dQ�p�~SosЂ� �e������}���LB�Е���?n ������8Kz��J��s�͞=�ĉ���G�������Ν���������III5wȘ@��F\RR��Y�h�f�L&�iM�%�D"���4����JJJ]��}V�ن(��w�Nį��V�d�M ���*��<c�t;��$N����)yn�T��݊<7���~��1��߅��_M�-�K�kݗ��oN��z5 �)�� ��r�������Y�#�L�X�H)��ƌ�KCu���� 5,r������hHз1ؘ�˲K�D;�]sl'2$�)��}���"aJw� >�iM�ԉ�Kc��j\�ߏ�H@���-��GL�;fR/ʦ ��MI�Jݧ�F��"���|�lT��EA��|Mۦd�o�x�l�z ��ȧǐ_����+Bh��\����3��Ѓ��2t"��yK&���4�چ�̫l�Îr���+���d0GS _���}B���EK��ի.\���_�:����W��~?{���ܹ�e�TTTBBB5j�z�jcc�����͛?��իW�6m��h�W�\����m߾}�͛���Q����z�L,Abh���DZ<��~d����(���p��-!4C�4-���dɧ���TZQ'�鑭 ���\��횑>=ɆZD�&,���3�%�;o��M�Fz���*�ᩥ�LV3�m?��Z`eD�)�i�����͈�/�����+�X��p]�!�g��������hCq`�6ր��D�;�\����p� T9��6S*���ї�X�ikB��B�K!�-3�;��X�Xu�Q��Wi|;B_�H�C�����Y�,1��"�I=�V:�4zY�w������M��V���D��nVĸn���q�LQTe1�T٨~����h욐'�h�h� ����>4��K��/c~D�Ё�ZO�U$��B4�-�:)&���2�)�|\ !�p��R� 툡��c!�V#�Gr�`�I��Iuͪ�JH]o��;�8q�������,_������8�Hԭ[7� ���233[�n���X�~�![�R��gN"��m �Lғmt�-8�F3� ��1#�i�ID*�~ɯôn$�c�Q$�1��l�ϲ��r$2��2��$C�[�'���jb4P�t%�[��!�UX�HZ�Eeh���]l�S�� ��Rt����gk©-��%Rr����U,Q^� �a& �")d��f �pkŞS�������(:&�_��EBM�6#�d#��u�M��\�/�*�[�͍fDV1*���fA��!������p�ݙ�ϔ+�DmpnK���m�>>�.����,�! f��:�Dr�ǫܻ<�ܐ��Z�'�J ++�)��,U.D�ۊ͜�L�� i�e�ǂ|���6 п0T�^�I�b���8i��&��3V��BD�`���X��;Ce&� ��.ty��9B@��E藳�K3btr|�VV�(�I���o4O��322b_���/lmm�6nܸq����VT��L*e:(��J��:_$c ++$�X,f����L&�("�"�~QLw�+��ԣ OD�N ajO�D��\bnork�#�r%�Lt���*�nXgV�[fm��+{2��@�iEN���^� �`�@�����ʈ�ٗ�vN�Ʌ��T��e.�lN�(�1��D�髃����]I@�_q3}�� ���f�`����Ҿ��=�d��������ǖ�`h�҈�-�� l\"ޡ �d#}�F"�DY�������$dcV�����"�������\^&FZ��6�>S>E^>����K�@�oN&�M�+O�F�ʂ�v�H���/��B�'��Ġ���FI���m(��ӟ��� tiN��DZ$#����eF��G���S����J�lB&�(�h�������jjjA�tɓ��˸�4��믏�"#�i��ZBB߁K3h�M,�,3V���Hk32%m�͵`vj�H��$��XT,DFZ�6��������>�YZ1�@^����� ��/�M���PC=[�`xkB����f#s�GS"�Bx\"1�Jc���TX����G����I��tՉ�\T(@��P��eY���{t��i�B���~��˲�������]�qoʓ]_�W@����&,u�]c"!�dK��=;�V^���y��1E���&L� �2UL8��3����314���w� ����K��%�)UR,�/�f+6�bR��MɤZC�}�<����?g�S5X�S%b��3�(Pq( N������ h�O�"����ᖐ ++p%S�>Gi�1H*��c�l� ++\.��*K� ��0�0Z���XU��(�L&��|Q��F0�;U.A�{S ���9�`�ڄX�D���g��=;�%���ː�*��!��D�����,�N_y��^jj��cQ�H� ++ ��X�P�`���u�<"!��)s��v��<Ne�F3 �PaI��������!A��R��_>T��*���� ++ ��ȉ������e#��F ++�A:� ��1�Dn1J)�P���ln�����%z�@�Ћ���^6����QQq; �u%.�1��>u7'��vjMr)���qj9����TJ6 ++JD� �����ǜ��%��V�gJe�A5?�@p�%rnK�X��?0Œ��X�%(��@X*j�����DY,�K�2��y0��y�WH���5�&�O��%�}��'��p%Srҿñ�R)A� �DBEQ<� ����D"��Sg���V �����]!�H)��t{һ'��?��@�O��bP��C��A��i��ԡ������_�� ��M<U��]X���m�a���=��6SyIr H�AAgK.4�"�'VLNj>b�n%�N�(�$�I^��pI�K�thD<M�g'J�]�� ����\Թ��%R�5AR�@` ++L��s`�jG ��Dn�B�V#�����;���W�ѝ(��G4�4����t��ɒ#��2diH��0�`n@��+_z��ϔ ++*�O-������V��7%���ڛ���7W�"$�T�(� �����O�LZ6�z��b4�"�ؔp�Hz�����w�}�C'S�<&�J����p��!!� IR�w��a�[����o�T"���Ӄ�ўG4���]t6&sЊی�k�L���t��S�,$ +]9P�q�����T@��{�:'*:�HPcr�CfD+�ʈ�����(��ض�(�֛x����L�8L�愠]}�a����������^�8�d������Z�@D ++�`iB�K���x(UvU��*�?�z����g��F�l�2� ځLLgRƐkC��A�9���Pgs2��ib@\O�TX�w�a�?��E��`�˜(Cm�D����@� �3І�P�j����>���i�����Ƙ0�;�u�����EU�A�ec���'f��Mի^A�u�o�ZTXj?��ZDwS�SS�iC���{Ο��]s2�y�Ɛ���K��X ++b��������WB0���x1���xR�!���� �LJQ���H#��P&�I�R5�����J��1�7#��zO�<�{Y�5ɔ�qH��d�E����3c�P�R*d2@�Ja�5���(;R"E/2�� ++z���7 �ړ*������LGM�x��ߛם�)F�o�*͇�O^ ep>���A j�q���$����C�!Kʇ��A,a�s?�m������*�E@��$��`C�lZj\w���P�������_��7�lV/j�0*�s.�{O��Xg�ن4������۩���u���Ƀ�l�r)��=�C��dI8�c��hRO��)ݬ|r�L����B�eC(A�@蓅G�uǓ��$y�������ˊ�� �ޓ�{�t?�(�����[gu![��L���5�� ��I�!����JtjF��c2ʔ.�5�E�<��6��D��Jc�T�-���V��=s5��ii�A����$ ��\���b�!���T�j����mz5�_��7iѐH�E��ѓ���]M�ђ�Є,��G���`�|���������xF�u�!�ޅ:���}B0%��'����1�|��P�;}�OH+=X��y��4�#�t��$:�*,�|�Q#��@,�J���I�qK��ޣ�6�_�~�V<� I��r��!4M�0�����m�4h�%��|����/2"3���̸N�:��@/ ++��V( %BߕC#�V�C^e�z�ڄ8�@ �1�v�3��^����]�plF�h����x��l���90� akN�lI�@�0� ����� ��-!X����ޟn �v�K/�?|M�$;K:�P����dg-d�.���F$���P ++��!�F�~Ы ++�a�a���T�������`������2#c���q���"��������/Bj|���q����/��~�CR��h�0�j ++��TWB0ePm�n �'j�d�ܢ�� ��' �<v&CrE�~.��;^ۏ��0�0�j�'S��2d��f���0�0�;F��� �a�a��*��) ++$u}�a�aX�P�p%S�D����0�0� � \ ������e]�a�aVڛ�O�l͈6�u}�a�a�Wkc�Mp%S$���(\�0�0Sjm���^�gL��ܗ̘^\&}���F�ť��R$��b�a�)3m��5%H@�k�JVǾ�"�n��a�a�D�����0�0�j��`�a�aV�p%�0�0ðZ�+!�a�a��*\ �0�0�0�V�J�a�a�a� ++WB0�0�0�U��a�a�aX��0�0�j��`�a�aV�8u}�V��=�w����Ցoq0�a��{2�l����ƍkҤ ���ӧ/^\�h�S��a�a*��?��)��V���@ ���(����I�&U�S�a�>S�=�H$� 7l�P����x<�HTVV����3g�|��=�ܹs�s%3gΤi���Rg~��V?�.����%33����<044tpp5j���J��H$�3g�DDDdee�����ãA���8p�G��4i���[]�wA,ܸq�}��s�̩P�|||,,,fΜ �B�pƌfff+V�HJJ�����$-,,���;f�---��������$�d��� ����ڵkד'O�������\.��={�СC;v�;w���&����Κ5+00PUU��Q�222�>r��y����5kΜ9#���ŋb�x�ȑ����/**:~�xxx8I�C�5jEQ�z�5 ++�)�*�F���+� ++>|x�ȑ��Ծ}�N�4IKK���'66644���넄����o���ݻw///�ڵ+��Q�Fvvv����aÆ�/��{����ѣG۵k���kgg7eʔ�:88DDDlٲ�W�^-[�ܽ{wjj�%K����JJvz`X��N�JE"@���kc����[��`�������.m6����C�;�6������~�۷o���E"����~� ����d2������o߾���D"���9�����yw���5���aا����}�v�ƍ 6�3gΧ�1���'�J-Z$�-ܻw�S�.\�n�:�����������״�sC&�͞=���d�ƍ�^����? 99�ҥKG�mڴ�'�5�;��/�ԃ�0[�nUl9,((pww?�� �����:t��ؘ�?z�hYY��ŋ�N��k�g��]:j�>SU.���FQtt�ܹs���W�X������kv�@ �����v��� ++.^��̙3�֭�r�S�Ne[����oӦM/^����w���x[[[��� ��{����7���y߾}!>����r���!C��������m*�n ��[Vi.�A�ZZZ��l��huʶ,I�/���G�M��_�w#���T��e�x�A�_�'Bh���={�\�l�L���n�Сaaa ++�U^��\�����ӧO����@�=D"��$�S_�aU*,,<q�����[�haaaq���Ǐw�ر�AAA�o�>|�����|������!����Z��a��GEE�Y���R#>�������^^^***ӧO������|��i�^�������W�Z5u����ԧO�Κ5��RSnݺ��ٳA�ɗ�����߿u�֊��߆��jjj��������w�w��MHH��`�,�RA����*0r��ٳg� ...�СC� ؏���oݺŶx���DFFV��`llܬY3���� ++ ++���j��H���ڡC��g϶i�Fq��˗ $TAČ3�bqXX�����%&&��'w��aZ@_�B��Ha�-��>���0�2�� :�QRދr�8���o�m`�j��<��(���r #������6t�Py�������[hh�˗/� �nnn:t��ɑou��9www��A��|��u떷�wLL��������ŋ������@YYYpp�Y�����l�RVVV��B�n����ruu���/))a������ݻ[�l�۷/���@ ��?�:o��lva^^���띝��Ν���+v�&N����e˖���*�(�w���d26�AUU�s���+z����������r�ܿ���E^�?~����W(Qv}67^�|٥K6ƲI�&�$--����M8I�yyy�p���3fԃ؉������/^�X[[[�033300�o߾��ޏ?V\_*�n߾}ڴijjj���H$JHH����ݻw- �gJU�*�\vvvBB����T*k���� �IDAT�D���?��ӥK��<x�`�С�OaB��{�������&Y5O"����v��=..N$I����R�L���Կ���R�X\TT����^@��m0 lժU||��k��6u�3-!���F�����-�C�O���#�eed�$ՠ�>iB4P���H ++����6++�6l���q��ׯ_oԨѪU�|||�n�ڨQ#]ݏ�^�$))iܸqU�0&&�&L�дi�7oތ7n����Ǐ�v��ʕ+�m���͛���1c��x�͛7�8q��ݽ�]�ti].��� ^�`���?{���;y��+Wʏ燲}��y�����:th�K�. ++����vvv6lx�왗��ٳg���g͚�z�j��J����� ++K�:)_���@KKK�sIWWW��̊��g��JKK+|���ľPUU=~��|����{���ʕ]�͍�������TUU ++ ++6l�~ڢE��O� ++�Bkk�͛7GEE͜9�O�>�����{��{���#22R���ãy�榦�7oޜ6m�ٳgMMMُ����<���'N�ׯ_- �gJU�*�{�}���C�����;vΜ9�*}ǎcbb���s�ҥiӦ�:uJq�ٳg�_oذA�Ɖ ++[�x1�:!!��¾=z4�,[����d�����r�Juu����:�[�_��>��M�$��`�� �Х%%���b��U����Z�K�R555�����9۠,ߤ�Qd2�ҥK���`��Վ������0bĈQ�Fegg�k]�v4M���k��{�'OV�"��7o�<y��������ѐ!C=z��"���M�0�k����ϟ?v�X�())��?�����yyy�ǏWUUmҤə3g?~leeE��@ 055�������� ++K�A ++a�2���jjj�m۶�]�*��߿___���,<<|���AAAFFFb��ڵk����:J�]�͍ ++o�+;v�����ˋ��ttt���?�̙s��E�0a�kk� ++�'�BTTԝ;wN�<Y!�����ɓϟ?=|�pv��������6��Z�hq�ԩ����۷����1�����3������Ĥ�#' ++�a�k � &XYY <��tȐ!���)))666�����ܹ�D"y��Ųe˴����3gggggg�LV��=A��%K�{�}{BB �?���5p���;��}��"���D� ��ٷZ\M��(��-�/�� ��(xl�o�gc>|��HUU�U�V�|U�w�KLL qpp`G�����Dr��љ3g�:u��������������U�V�[SSS]]]��U���ȇaQUU-**�w��:99988�����۷EEE���ǎKJJrvv>p��P(���N��������kAAA��ڶm�hѢ1c��4�8�4jԨI�&�[��������������Ν;�A�ʕ]�� CCCy�byy�D"���mР��y�@GG������2$$�{��lF-'�F<x0//��ѱC�AAAG�eg�Qeff& ���l�Rq55�-Z0`Μ9[�ne�PF�L�y1�l�����wwwMMMcc�>}�(vF��� �|����[�����4ibii���:jԨ.�B�jЎ;�TE�HR��������:��5�l%�;��İ�IEoKS�v��m����tP���Mɻw�i��� e��o�d�� `��RmhhثW/������3gΰ���P��dذa'O����#����XXXL�6-^A˖-<����ݻwϚ5K>�����뫫�'''�edd�'� ++LLLڶm'��~� �,--W�\|�ƍ�G�V�Dy���s8������>����������������ٳgOfff��0#��[���(��$%ʮO�����eTT�D"���.��Ʀ�����ٳ�g�>p����� ==���222R�nWK�.=�<x߾}EEE�e��������|�@���333�RSS寅B!M��;>SUY�,0�:�O���������PXX�8T������������P����*{�|�|||b�M��QY�=������ײe���h��t�8� �ð�!@��ն����&R�v<ݛ_^x��)u��=7RU,)^�3&��A=C�/����bҤI���}�����oٲ%�������^VVfii)��������ᡡ�������� ++;www�4i�������X,���urrJKK+..~��Eff�c��5+|Ѽy�����>!����;w����_�����_mڴ��ё��'&&>����?vtt$I������;w�TXR��Utuunj���?eʔ���f͚U���߿PPо}��-[�.IMM----++�v�EQvvv�\�rE~�\�UenH$� &������϶��&&&�����þ}�<<<�nٽ{w��߭[������%�{Tl,��ѡ(�I�&��y����ŋuuu�w�ή�ޕ�c�JKK'L�0lذ�ݻ9r��f�UQF�LQt�����@1�L^`�`�֭>|�������������}||������<���<y���ʪ�7fff�}�V,?y���ٳ�8�5o���l�E���U�LQ���r��q��C�ں�+!X��[��[�j��U���s��I�+�7Ҳ%�WX33+�U��wkiiy���������CMMm̘1���l}CCCc�ڵ�v��}���5k�-�x�ݻw�<y��ɓ=z�8p��bD5�u��<t�P``����СC���{˖-����ӧ�رc�9R��� ���q������̟?_yo�5�}��:th��庺�����H$m۶}���ڵk����G�) +++,���Z3f����m߾��m۪Ӊ��̞={�ԩl��1HM�6���;p�����˗/����C�W��ZH�ר�!===uuu��p8;w�ܱc���/;Y�|C�P��~�=�3������/ww��T������־v�ZRRR]����Z�������i�6� %U^�L���T��������@�=���5k֨��mݺ���=z�`��W�~�z�044���ٷo_�N�j4A�ayz��;w� �c���ٳg![[[�tQ�����2��L�����R� ++��ՙ/y2TM����/m͵�0�+ICPE���I3ZN��d�:uj�Ν�6mj߾=M�?������ѣA���1�|��P�l�Re�����������zzzzxx<{�,&&fΜ9mڴQWWg��-)))))QUU�֭[�{�+�2�%������G���#F��iz� 쬮�����1L�ܸq��@g�X�L��XXXlڴ�gϞ��<y����urr�������e2YDD�͛7<���A�4����x������G�[B�:��-!�O(feeiii����ȡ��a�U���z0��P.ep%�cJW �0�0þF�����0�0�j��`�a�aV�p%�0�0ðZUc��W�^?~\>mjaa���?�~qqqa%��b���o��� ++���k�1�0�0�}56DoRR��Ç���ٷR��֭[s�̑�p��)vV���H$��������pmm�7o�G��ҥ˟�����N� ++��/V���0�0�0�GVc-!/^���������̬r,#gg�+W����-[��������u�ʕ��PŕG����/_���a�a��j�%$..�իW�#FL�:��g�j------�ӠACCC�(/////g��Wqo�������@�����b}����K�.���5k6~�x�G����l֬��ӧBnnn 6��/�iӦY�f�|��a�a؏�f*!�c�>㚺���?7 I �%S@�PD� ++��MՊQ��Z-�Q�uϺ^7"Pq�ց�q��wȾ���p5oh�K��������s��=����ٳg��� 4��?4h��/_�|ժU<��W�����APP��S������������F���I�&ZI��M*�6lذgϞ��b���5t�P������g�6k�,>>�G�l6��ɓ#G������XA!�B��v�cݸq��|>�ܹs��ɉ OIIٲes|� �-[fgg���lݺ><+00055555�����p���3g�������i���8"�SH$333�����P�)CCC&099�W�^���yyyVVVVVV9994M�9s�k��r�B!���BO�R�����G�eff:880O�_�~�̙����۷���:~�xhh�i�Z�ju��������2����˹\.�S�N͜9S��s�Ν;w.s<d��X�`A�>}���X,~������mmm���4"ddd�4����u��),,d�ٶ���=rtt���ؽ{���K�>}�lvm��=���:B!�� ,��JHZZZnn�E����/6����bggWPP��NNN3g�\�hс���3'�����L���Z0:v�x��i�X<u�Tkk�s�r8����1cƴo�><<���i4���ڷo���cdd������_~�EcP�Ç�6mJ�t��5..���^�z�<y�O�> 'N<w�ܣG��6mZK�@!�B_'-TBZ�l�m�6cc�K��x�o߾̭-�[�n4MW�6�ر��ry۶mcbb�&yFvv�ڵk �,Y�TW������~���9s�6���������3�5JNN�������^�z1�����Ǐ�K�.�m�V*����s�\KK����N9B!���i�B���=�6l˖-�V�R��f��<y�$''gƌ����3������[�|9�s���>!�������PZZ:mڴQ�F���W?�_������$///�w��uCC�{���d2///��J�B����X�UeeeϞ= -//���S(999��ε��B!�����%%%gΜ�f�O��^�JJJ���_�dIpp�ɓ'@.����wÆ ����333�������)S�\�v�رc��7m�ԠA�u����ٍ9R[��*:;;3�]�~}��WPP�ڿ�9`P9w�?��255m۶����]\\7n\��G!�B_7�-�;�|++���}ƌ>^�n3� ++�h��x��#G&M����gkk˄��r�������aBlll�ׯ_VVfiiibb�zSSSKKK}}}�$�+ֲe˖-[������������7��0@uܶm۶m�~�"�B�o�*!ׯ_�7o���ͪU�,--w�ޝ���n�:f�#<<���2d�á(J��X5k���BX���������f4��B!�B���T��n!/^�8u��ȑ#Շ��4]PP ++��###ճ��u�d�[�n=}�4 ���� �3gN� nݺeccӢE��$}Qp�]�B�o�TAi��Puh��̻�V$��PR�� ���(�V���;��`0���s!�B��F��}B�ed)��F�u��^�6� ��� ��ˉbh��@�c��O��e��l�ZL2B!�з�@���XE� J ++H ++H ++ʷJ I("��%,("�$�, ^���D#�B}��'�6:�ߡ�ZI�}7 �H ++�Y�v�L�m�һPt,>S�233w�ڵp�B��;�&��%�X,�D̮,o�{�.I�6lU�!�B_�B�p�����z��1!iii���s���p4o�)��(��9�r�oǷ�s�u�ߜ"�J �����m��p,PRP�VPR���� ++�>����ױc�=;bĈٳgk���>���M㩨��ŋ������Yzz�ȑ#[�lٵkWGGG����o������:ɉ'��u�:�P��ry<^m'�k����g�;�� �R�zb�X�T֩SgѢE�֭#���[�:88H$� ����O�>g�''���χ��i��]�v۷og�ٵ��Z���mtI&�() iP�o;:H廿JP�P̒QB%�b���aZ���8p�ԩS���[�n=u�ԩS�~��G�8���999999 ++����5>>>���m�~�}���Ǐ���w�� �Ç����[� p:�d��è���Ǐ����ׯ_BBBm��K!��V�^���?mڴ��|�g���֬Y��������ӧ+�ʻwﺻ����7jԈ�I���L��7o�lݺ���W}�4� '''""���͚5̢��0g��PȄ������O&��\�?��W��;6 `Ŋ�������<y��:L�:5##������`��Ν;���=~�X��?���lh^)��͛���}��^��r��a��͚5����Z�n-�HT1O�8�����D? `yϟ���Z��n�z���W�\���jݺ����ٳg###[�n=f��077���>|xVV����͛7���֯_���^�zyxx,\��VB�����\I˘z��mG���_ ++�̤L�U&�*�����]��_����������3�888������XZZ��8p`�w222v�ڥzXXX����x���������X�N�C{{��u���d�o��ի322֬Yccc3~�xU5XEQK�,���s��Q�FEE%&&Ι3����,P���9__�Ϟzm�xi(�q����ۯY���ӧ6l��Ǐ'$$:t�^�z���L�ݻw����zoە+W&N�ثW�ŋ���?}��͛7+V��֭ۺu�Ahh�P(���4h����ڵk5jZTT�L�lϞ=�:t�аa�j;CՂW����␐�C�XYYAU�������_��z���<% ++o߾��Y�m���Ǐ_�r%��1bDEE��͞V͟?�~��gΜY�~���_zz�������v���D �ի��͛i�600�ݻwll�����W�v��eoo_���]8�8E��f���Y���X,�fnH� �=�(�J �wSG��>���b�X,@nn.sR\\�m�Ν?<��6mڴn�:������mڴ�_%�ʊ�����������������{��//��1��ٓ��������3S�4hМ9s(�b�ͥ��)))˖-���h�?��͛7sss��¸\nxx����G����ֹsgccc__�ٳg�?����iiiS�L�żTEQ����ٳ�����Z�b��>|���622������vwwgn���^�z�6mJKK�ҥ�P(422���<�M����!//�[�nM�6U�|��bmmmmm�'&&:��LJyhhhx�̙���3g�|����;;;WWW�011������e��תU��6k�L=<!!�w�ު� ++� &O�,�J������U��ݻ�|�nݺ�����h�"�һ��o��I92�{�������G5��bq�C������ޛL*(P*ߎ���:��� X��l͈�/�ׂ��TǣF�R�1�_�gРA=z�`�������###mll�]oa�u�ׯ?v옛���ٳ��-((ؼy�_����������ɛ7o������=z���u���������$I2s%y<���7�J�-99y���;w���FQTIIIrrr߾}U_������̸A*�,����v��q�\��W��\.��H$bn��`z2�l�2y�d];������ʌ:#IR�S��V*����G����P��2�r�\���A ++�B�����������;z�h��s� ���;v�X�xq�ƍ'L������Leϟ?���:w�*d���{��022�|���Q,�������>K�>�\.��:v�c�WWW�\. ++I�,,,���JHH`�(J$�{���3{wѢEqqq999�:u���*-TB~9Je�V�<��AQ����K�G{��N���r�� ++(��YU!�@I�A�����EGM��p��Usss�H��驚���Ů���������k2���T �b?U��-[��^��ڶm˄0��U}&={��4iR�)nh���3gΌ��ؾ}�ƍ-Z$�G����z������<yR"��;v��� 4�v�\.�������TKQQ����������<//O#��۷�QF� *��;>�� ++�x��w�}��U\�Xyyyfff�1�����EEE6667n�`�ussKKK���/NII��_���3�� �IDAT�k8#ZQPP��G�ٶm[EE�ȑ#�N��T����ϝ;gbbr��!�����S�T����F����_VV��o�I�҈��Z�K�ᕢ!44�������̙3̷%3����ӧO���S����ťM�6ׯ_���?|��� ��ۧ��q�Ʃ�Y��G|����T������кuk�1�k������X���.]*Ν;�\D��:���p,��hR ��������1V�<���W����I�R�X��㒒�\��˗/�繚��5l�p�رǎ�w�ގ;.\8t����X>�ߧO��[�6i��S3�-�5kVHH����1��Ϟ=[PP0j�(����s���ƍ�X��� ++��#G@vv�F�N#Bc-��#g�)�˖-k߾����ڒ���-,,D"ѹs� v��a[[[�Lv�رI�&1qt����44RE���ך5k ++ ++ ++._�ܭ[����GDD>|���GFF2���CՇ�CD"�Pu���P��?4jԨ_�~�0{��1c�=zt�ر05}���\._�z�رc��G���W�����M�6m���:t��� �tj�pqq9x���+W�JE� ��8q�F`�~�N�:ՠA����[}�G�o�����-��?~<}�tcccf�֗/00000P�P0͔�P]cƌ�6ms�=!�0�fMoV?� ++{C9�]u;4�9,��嚛���~�S�-S������M:gf��]Kmºz��Se1}�^^^����whϞ=�5=ԗ�b��:u*�}����ۅz�a&t�5J=�ĉ���FFF��� 4������733�p8...����1'1�|�ꠤ��233���;v�ضm[oo���;;����{��u���?���X,�R���.�P�jv-**�<�y��g�>|�R�<p���Su�֭W�^ӦM'M�$.]��������fzt����4�ԩ�j�H$r�������zƌ!!!A���:::���?~�cǎVVV;v�y�fM�D���#F���u��U5u������sΜ92�L5����իW��b���:+++�$+w� ++�R>��f[����#u/^�`~������<y211q�������ں��4lذ��������:dժUM�2u��*�3=!�~������7^��c>XJ��;�M�2R J%P4���p,�=C����S�B***6l�4����}�n߾��z��!���̪����/���V����߿���� ++}}}ϝ;�1������)--uuuemb���y��111 � 6\�d��?���O?QV9���\}...'33�aÆ2���ի��>>>�Θ�f��ٳ����F���b1S�KIIQ��C����PM#vww߰a�\.�r����\.��������P(����uZ_�zenn�����ץ� ���&&&��w��������ޞ���7�$)�JI�����o�~�ȑ�{���ξx�)����R5�M�������� f��D"y���A����0�i�V}��|���477�ݻ�� :��w�ź�WoDD�FW\\\JJJ����� 6ܽ{w��ű��999�k�d��ñ�n�e$�4�v��*b��;��J��������GdF2���1���UsB=zԼysUK|5eee�π��˫�>E]�m���ܻwoРA���w�� `:�Ο?�R� �33�#F�]����~:w�\���[�l���ݻw߳g��͛-ZĄ�x�B( ++���Ǐs8ooo��U�N�VqUYr�|Ȑ!���6lX�֭���7l�ХK�M�6���2�a�ӧOw�ؑi)�ر������̮]�Ve���O ����+V����x���ٳg���w�ȑ���q����={V*����P�~��M�6-Z�H$ݿ��b�������ȑ�������֭�2e��.��W��C��:uj̘1���������;v���˖-������?��>��>VM�G�����7��TvvvFF�L&KMM��������9�V�X���P[�*#s8.���r�lv�㸾5X A�� ��\H�(h )fY��?��=�߄t=͝?䯿�R�z�IIIZ�Z�x����w��iѢ��N�M155���ھ}�̙3��̺w�.��[�h�����~�M(���wȐ!b�X#��^]�'Oq㯿����iӦ��餧��믿>���gB�5��ׯ���]�N�'O�XXX���*` �:*�EQ����=���ޖ-[V�\�믿N�0A�B�X�y�樨(��I��,Y�u��oo���L��X�y��lܸ�iӦ�7�O�NMMmٲetttݺu��Ҙ��Ν˼�YD....&&��~��ן6mڧ|=~��JQ 111a�"v��a�ΝL�W��������|>�����;f�~e��*u�����ܳgO�6m>W�>��3gj�:t���x���h�nݺ5��b�٦��{��Y�n]������y�(*����5X�W��-C�=C�7�4MI崉˻+����Xj��������=�̙3�fu��Ǐ3-111$IN�6-55��~8~��'�q�l [TT4t��K�.��H�Ϟ=�ׯ�ŋ�ƍ��ͣi:**���R,w���ԩS�1�jRdd$A̤�Ї���MY�t�]�*�w����?����������>x��ڵk͚5 ++�������������u�С��^�� ++ ++{B�nc{�'��������7Ҋ���V��~��=z4y�d��011a�X�W�>}������ŋ���h��џ����ݻcbb���G�YydFF������Ϳ�����쀀����ƍoذa�֭ݺu���XE5�ĉ�!(��+�ҠA�u��i�fee1Ǐ?�ׯ߈# ++����O�>�e˖7oސ$���������*OC�v`O�e�#K�������͜ ��<�+!U� �o�[?�� ++��SV�TMr� ++�L�ޯ��i@!�ЗC�T�����TAa��<���Y�� ������.�W���T��`�:/����ݿv���Y�5�BH�` �#�'�2m�"�v����� r�{s?T�0�M����ZyG�B!��*(���Z��/Y�B!���c!�B!�jVBB!�B5���ۜ"�B!�t�6� �JE�2�\��s������Ƶ��B!�u�Z%$+�Y���������sl��ʊ�s��-�>u�=�B!�>�v*!Y��Dac��Z9�<ɸ������B!�uZ��^!.+//v��Y�S�/GC�Ve�"QYm'!�B}m��RQQ���W�<�K��E��Im'�bqm'!�Bi�L+����R��U����2!�BH�X�k�"�B!�j��NB!�B�[�=!!�B��=!!�B�D`OB!�B�fiau,�B!��t��1�Z�[TV�P�4AR4@�f'�E� �P�mcQ�;� �B}˴P ��*���?�҈De_�N��H"��.(}��E��Tai�\*�2��olf��̳�����T�ǭ�t"�B!�VzBpZ��J7��/\~��.����E���;�\V�����u�G��oú���p�B�o��J�@`,�up�����UVzm'�e��?�H�w��f+�J� I��i�$�0�߿��f�Xo�?���-SKk��hc�)o!��^�zՠA�aqq�\.g�y<����g�B!��h$I.Y�d������L�����O�δ���(����'��ہӑn+(>�s��(�$�r�������\ﻮ�9zGﻮ���q��l��r9SEy�z��L��oq���������3W�^��m۶��mݺ�U�V��ޭZ��8������_��y���� ++�LV۩�����5�ʟR�� ++^)_=�D"�H����.]*|g�Ν|>_"��D"�())�8q��ׯ�ҥK^�L�8�i?�6}��/�u�%e%�L��Ρnko_�� ��i��553o�����RIn��(+.�����[��:u�/��mcc�T*�-[��������C�ݻw���ޠA�bcc ++�СCϞ={��]-�U2x��Q�F�vB�2�l˖-gΜiѢŤI�������<y����ĉ@,O�0�����~{��aHH��X,WW�.]�2���X��۷o{zz��u��K�$�#G��9s&++���?44�������###[�j5e�###�(((߽{7�ǫ��hɍ7�������.]��5��k���8Pㅩ��-[��<x𠫫k %]��JQ�����ũ&&&:::fffnܸ1==�����444�xU�e8y��۷o'%%��|&��ӧg̘�a�___�T���Ä;::�i�fذa����t����D�cǎ�OEGG7k�l���fffmڴ3f�Ν;;u�t���U�Vu�����}�ƍ/_��3g�ͮ��t��@H�D*��DE)�ׯ^�d2�\^TXx���?W.�s�����r�\����\.�(J"�%�Z ����4��/y�Ⅵ�e�8u��y���ҥK_�~���ڣG���&�֭[����Z��6l���\�lY�:u&M����6��V�\�P(�O���-ܺukll�i�RSS/^�� ��ޟ=����Ҹz��s�F�9o���3YNOO?z�htt���ˁ��{���駟t�r���)S�t�����~+((��Ȩ2���.����H[[[�^<ZM]}||t��Q^)ꊋ����U�_++������ǻ��3ٟ5k3�R݇ʰ��"55U�ԩS/�9sf\\��ŋ�\�?����Y�f���$&&�\���KMM���ܰa�������n��D>|x��ݷm�FӴ��A```|||�����l�bggW���]��t)�)�J��P�Y&�VT���M�F� ��>9����1������:;�3g�T|Ҹ������ ++����|���狋��4i�l6[.���������r� �t�¼�իW<���W?�X,600�n��RIIɁ���נAWWט���w�jժr�����?>**J�u����������.\HQӠ[VVv�ڵ����2��X:thsg����d����;v466���^�p�?���������^V����M�6M�6-00�Z�lID����|�@RR���Qpp�z�W�.]�t���ԎW������]��������"�JCCC�������߿߬Y3U����@ 8w��㑟���U�����-�Bgbb����������PV����l�2>>���C=�رc={�T5U1a��L��_��~���r��%����=!H�� ++�\.W(2�̾n]�B~�\��n���1u�o�_Q���~��sI ++�ܡ��L&#IR�P(�O9bbb�>}���s�ܹ���)S�,X���riѢS�HIIajA*/^�hڴ��}88�TTTl�o߾S�N���c�,Yҽ{�)S�<{�� �r�Jhhh``�U� ++ ++ ++��]/^� I�i���x^^^����r��ʕ+�,Y����EQ���)))����!%w���;3�B���SJ��f+�W�^�9sf���,K$1g�X�����cǎ &��؉���{��i�F�PH$��Qe��B�X�v��q�����ã�� ��� x�h���ٽ{w�.]��Q�"���̌�<���h����V�Gʰ��G�e�\�ҷo�*[��b��˗��흜�>s��F.��B__�;w�H$�B! ++I�,**ڿ]�B�L&+--���f�@���0ٽ{w�F�RSSO�<Y���u��z�C���$ �]{�����d��7Y"���w�Z��4�u�g�39�=2����ԯ{�S�@����CBBBBB�̙�M�4�1c���snn.��5k�� ++ ++ڴi���������(�Mp�>}ƍ�y ++��g�ڵS�N�<yrdd�֭[�Ν+����ڴi�t��G��;6>>^*����/Z�����ƍ ++�"''G#���R-������zzz�C33���|�8����(#�Ps��nݺ1<o߾}�𔔔����nק��j����� ��N�:�o����� ܿ_,7n�xŊ]�8qb�Νk6���;v,22R$ :tҤIU�J,55���B5��QRRr���ݻw�|�� Æ �_�����ٳgǍ߰a×/_&''�j���ի�/_nڴ��K>R���έZ��y�f�Ν�=:nܸ��X�����Ϫ�K��P��_�5s�L��{�nZs<x�`��7o^yy�ڵk`�����ŋ�)U��V}�t���P�HRA��R��Je��4E�A�3�pd4M�����2Q��2��L&���l����?VVVK�.]�t�z���g͚�K$����~���G8x�T�/柠����_� ++����7o�����1���9;;���ݽ{�aÆ,������~ذa������Ә6!q�ܹӧO{{�5k�����2پ}����H$�p���ѣ���occ#��N�<��ѡ�����r�qqqyyyQQQ�-��?Z�j�aÆ��«W������?��4iRbb"��߲e�ȑ#7n\�N�̇v��b��(��ɓ#G�lذ!3�X#�W�^�KRRR�v��� r��]CCÆ �|�� #G�dF����p���̝;w�ԩ$I0������B�%/�{'%%���>��y��o7k�,///�\��ɓy��k�u�Xݻw�;I�U�q BU+S�c�w�}�v��{��-]�t߾}���=z���Dyp8�m�BAQ�R�������s�LniemF�l��� �YJ������IK+k�L����Ё�L�E.�וkk�76i��ƍ���������}��U������{�������j�WZZ ++�/^�())�֭[�N�:w�YZZjkk�w�އv��}ǎb��rH�棺���+**Tͮ���k��@ӦM�O�>d��R���8:::;;7i�$,,��� %%�>|����,Ϡ[��)��b��ի���3s�̓'O>{����j�ԩcǎ�SSS77�ӧO���ZZZ2�0j:'�`nn����FFF����;wNMM�2P��7n��kn���c///�[�I^)�f��.�\�|999yΜ9�4������wRRұcǂ��*��`cc������֧O�A�9r�3gK�֭[*�N LOHHH��Ǐ[�l���@�+!H�)�rf!��4��L.k��Lh)�2�H�;��T�� ��G3�\��,���U*���'I��ۛi1�ݻw7lذq���q���n�/;;[KyE�;;��M�s'��������ۂ<x�̙���*Ct�����y��9��d�7n���i�iӦ��������ɓ7mڔ��S�<EI$���ڵk��t��>T�&̜�fT'�0��̷J�Ν������;v�1������u������Mu���3��%%%���U2�O�<qpp�8σtwY^�Rԕ�����3�R�4==���A�4��344|��Yaa�j6�L�����̬G�[�n�ԩ���]G�n�<y�����=*k߾���m����~��u��ti@��!�TB� B �e26�ө����c�s�@�N����L&+��c&�*�J����j���=iҤ�Ν;w�С�?�v�ڞ={4��5��w��Yy$1�1�;wk�������<x0`��+W�ܽ{��Ϗ�bq�\�K�.i��v«���lȐ!6l3f̅�իWy �J]��߿m۶y��1!/_� ++�"���ɓl6�M�6E?~\�;�nW��!��G�٧O�~�aŊ,�o߾'&&�iӦ�kj�={�������ڵkw��MSSӛ7o�����~�i�ڵ�'O��ʺp��Ν;�d�3w����x������u gϞ ���ILL433���-,,\�p�!C8κu�~��'333�X�z��7oV�\��e���V�Ƚ�����L�L����e˖ʪ��]�������ϯ��l6���r�\��Z���o��f=D$*��k+A��!� &����f��ʲ����dR����o�� ++�hhd2`hdTVZ�P(8zz���,((8~���A�EQ͚5KLL�ѣ�j��ʞ={����C���UC�Q�355ݶm[ddON7��� �IDAT�����������ryӦM?~��TTT���k���b�X#��^]&LزeˬY�Z�h�f͚�����p~������#�f���K�6mv��amm���SՒ���rT�K��isssfU������ٳ'++�S�N�g�V���۷oW�SN�0a�ʕ�v� ++����T�����l�������z�jf=�*��ll��T�J�7o*�Lt^)*Æ 3119y��Ç}||6o�lhh���}}}7o�,�˃��T�����27�/����3��+[�d �X[[7o�|۶m�[���YԾ�S�j�<>|���x����G�h����dJ��f����߿��ͽ{��:���Q\&�q�5(�q�� ++qY+�u됮����C���SZ�>2�6��ѣ ��� ++I�� ��^�vv�g��hna�%��Y�_��YXZ��x<�efnѻo��~�?%�Ϟ=4hPDD���GRRR\\\��m���͛�� ???��gժUu�ԩ�'dҤI��^}���� �`&�#�>��oʪU��b���r�J�((( 6lأG�n9i�$�@�,�[^^^^^���ڵkW�i�}2����X�q ܪ���*+������;�utr���e������7Y��gft�� ++@$_�KOO��b����1;::9�s���oQ���ի;w�|��y����ӴiS� ڶm���r��Q���d�R��V��|�����˗w��U[G�&�9s�#�B�R�)���˗/�С�z`ZZڛ7o�����^�z�$y��ųg��ܹ3;;[�Tr�\>�odd4|���H�A=!̭*VB�>5�fO��;|���/��蓮RE��\.�.���p�>P� h�g�z]��F�B!���T*u}���D;=!�.��J��u��� ++�B.�i� ��LXg�����9Uk?��e!�B:k �����LM<�^=�G��H$����)���}}}+K�ƍ����!�B_+!�+���k!�B:7+D!�B�(�� �B!�jVBB!�B5 +++!!�B����B!�P��JB!�B�Fia�^���B\^��/�HT&��v*B!���F+���8 �})�Y��NB!�����B%D 0��:�W�T_�r1�[�}���ӝ�'�N?a���⩯ë���NB!�� ++ᜐ*���}k#� t��8�� ++;�)�/�P ++�.���ne����!�B�x]�������<���HL����߄��E�*+CGwp�� ����5�j�CB!�Үo�'$�ⓢM<�i\��_;�0��s�R��|h���(c�y�݊���~U��L�@!�B���TB$ ++b�)��g�*$<d�ۣgg ++t���hK���|������SZ�-W�v"B!��'�J%d�M�!����^�_����6^auߩw�)��=�cU]�.�nhE����zȐ�z��P�i@!�B�S|���x��ڀ�/e�(�Dģ|B$��0��t�O��Q#3��J�O��C2!��8l��V�\��* 2"��Ԇn`YE]���XLXj>�ihE�ǡ{F��U�ɠDBe ����67��C!�B_��L��T�?�Y��K^�w�5��|����{�%M� L�i�Vo�E@RD]S:�1�ŌVҐSN�m�ln�K�u9Q.����5�E ++�ՂneO��9`ʧ�<b=. �-�M�s��攭�h#.�w1����W��>����M�PeB���g�l����6w ++%��JĠ�G[�X"aȣ-�� ���i.]P"B_��ۧf�����H()��H�J%E�t�]N�,�˶0Է0���;"�B���TA}��%�v���j���A� ޔA}��y )x]JHI�ŢylpA�Cp�E�H�2��,9IS4pX`ć:�z9ʥP "�e� ��m)�m����b1!%���E��1m��� +Eb(�Eb0���XL�3���Ӄ�U1�DW*! ++%�wN��kWO>���L"f��\��z��r�R�����;��?��ۻ���^uz�B!������T�8����)��wi��di��[����zf:��n�F}m����LB�H��""�շ1��� �ϡ9,��L322�cUWKo^��WB��ٱu��#�LLL�|��������A�X,�$�r�T*��R����<�π�cj�d���#�B�E��X�>�a(0��$�!Ye�� ++�(���*��b�mV�Els��)��۬#�X�_�����V��Yk�ߛ��8��r��h�R�T,��z�t����Lb|���A{ٳOs�@*�L���EnQ饋���022������l6���p�\===6�̈́��l}}}CC��q1�.^�)*�ķ�(J,�x���ÇW�^=z��m�"""���E��mc����ɓ'K$o/������P�B�~�gϞݿ�$ɠ��������������r��u�JJJ�@�P�� ��LV��P(�R5�� �BH� ++�ܹs333U!iii���'I�rd��Ȫ�`z�8Z��n(016�x�q��k���r��fE��� ++�6�˥��>q�O����6J�8��۔�V���Js�������Pƒ����2V����+m�c>�"�P�',�ۑr4�_��.� �`ʧ��[փl`IG�a'>b�v�pJ�?b���%MM�HHH}�z�즙����K����+<������h�&� �$}L��RN��yȄS�������lݺ����?�����w���&&&eee���NNNm۶���U�ɉ���r���o�8;;���\�z�cǎ�8)))����5z����s��e���Ǐ��˕H$˗/_�x�'O���{�g����������L`�v�v��PVVƄ̟??88�_�� ++�\.����vB�f���{��a�p@#B�W�WO,+��:u�,Z�hݺuA�4�u�V�DB���aqq�����̙���t�����0���k�n���l6�V�P봳:���kVv��'W��������(����8<�����T����+oc+ct��;�$�âM�ROk�����3d��<�K���\���h$-�pMy ++C�LJ�������CU��b�e�%��=%�44'f�8K�d���2�dZ��7C��H�����~m�埕���z��"���z��VR�c�� ++��t� ++������r����ߥe�O|���y�ĉ���111�W�^�~�����ׯKKK���T�rss���w��A�T:f̘�7o2�?��#s�t�����k����#G�<x�����ܛ���w�ر���{��g�~��M�&&&7n�`"ܹsgҤI�3ϟ??99y�ΝL�ѣG���,X�J�+Я_��c�<���E��d7n<q℧�篿�jmm��lXXX� ~�����cƌqtt\�x�����d�Xnnn]�v>|����#nٺuk���z���ŋw��=hРq��1����qqq�o�nӦ����]]]�_r���3f��-^�866v���mڴ�>}�������;6&&F'*��W��ӧO{������t�$��۷o�>;;�ѣG����`��u������:u�8q���%|��Q7o���ä���u놅�ݸq#99Y�0w�ĉ_~�e���:t�H$-Z�`�����CCC]\\>�������c����ԟ���lٲ����}||��o�>??��7o.]��S�N�5Z�v�/.\���@-.��`�jfbu;���d�B�X��".��B�����b���r}%&Y�`�W<-6xZl`k(˩����,K��C��d�L�)X"ό�*����M��o/�B������G��8��4Q"�d����0�4�fU��N ����R_^(��@O)R����� �0�*�r6�X��\��3�e����)sNUN-��=��2�Y<���sE\�0�+���ؔL�6�ER,����s�\��bN�:�u��R������$I�Tj`` �E�&/e�s ]V&�� ++���d$I�X����O���u���3�vvv�dƌ|>������dll�q�F�@0a������?##�E�����;w�y��ԩS<�9����G���DX�|9s<aaÆi��0#���X�PXZZ*�a����z��ׯ_�Y�&))i��U��Q�d��\>g�U���(ss����M�6eff�^�Z�ܹsÆ ��<h���ϟ?.�U!oY�b����G����z�� ������СC�qNNNxxx�?~���p�СC�EGG�?�v���5�@�������*&I�S�Lan���ߟ��0�|�B1mڴ���{zz�Vv������ٳgϘ1#$$d�Ν3f�غu+�Ū|�h(.. QUYU�sB������۷g?~\����oӦ�X,>z��#N�<ihh�r�Y̟?��ݻ�7oNOOOHHشiӰa�ƍgii9q��ݻw3�BCC7o�������{ǎ���͚5۵k���s��>!��_?2��Y����������Z�Iㅕ�O����ʧ�|N�G�Ye���}b�j8���W����6�\F�4�(�J�$i���dEn.r�A�5mJ�J��Y���0q���i��_ܣN�:5<<�C����k�p8˖-S�@._��k���/^��]�v 6����J��Ǐ������;V��F*�.Y�dԨQG���'r8����LOO����S�N�����H�Ը��cc5j���k�P ������剾������������nnn{��s�F[cϞ=III���������u���A�͙3��(�A���4%%eٲe5�m�ԩS�N��={� ++���?|�0s7idd������kkkU�xbb�СC}||8йsgccc__�ٳg�?����iiiS�L���ߪ�ׇ>0M�6eb�:u���8$$�"##���|||�`�ĉ۶mۼysme���JQ���kcc�!!!���yyy����/ yyyݺuS}ZT Ϝ9�TB���._���Ʃ���1=�&&&QQQ����_2�תU��6k���L �{�V�R1y�d�T�����v��=�v�֭*�(�:�Q���BAӴR�$���$��r�Y���L������xL=��"B�4��|�(*88�ٳg�֭kѢ����D"ٴi��W�y�����ى'���ǎ{��Ņ���_�|9--���`Æ ��|��ќ�������رc,P��VRR�jժѣG��:����'=====�����p�Ν���A����$$$|SB�ׯ�֭[xxxnn.XPP�p�BftS�������`??�%K����W���?N�d�z�����y{{�2�.99y��ūV��[Ws<������������R������ ++���f+�ʂ���G�zxx8;;W����QQQ�F���H�\�A��-[&O���*�����B�X�b3*�����Bո#ww�K�.1]ͺ�ul6�����3MQ���!���;v����=z��;wT�<|�0�Q�����/�D��Ɏ��NNNZ�F����B��cǎ�n����C�$���z��! ++�q ++YYY��������_zzzLL���Gzz��j;���1}�r9��M�$I������X��wi\XXhaeURT�T* ��ʘ�f��O|������={��?����_��G�EDDDEE1_�����۷��ѣCCCmll���H������%�� q�!C5jdhhhj�vB|߾}���������v��5t��={����2��ڵ��f�m��ɓ'L�X,V��~��q���iӦM�6�9�ׯ|`"�Wl���3gΌ��ؾ}�ƍ-Z$�G����z������<yR"��;v��� 4�v�\.�������TKQQ�������-�������4�ܾ};::����1TK)��|ՠg��x��w�}�_Mq����;w����СCOu���={:88���� 3;+//���---M,{xx,^�8%���w`U���g��J ��C'RD ���AibaW,�*���/��+���TEA@:RB�B�s����cֻ�Ē� ���ɜ33g.��<s�s���'���˯7P ����_��{����������w����Z��4mΜ9.����(::�J����ݻw�l�R� �E�G�NJJJLL�ꫯ����߫ �z뭻v��իתU��x≥K��?�|��̙3�� 6x��{��i߾�w{��"��k�Θ1CD�O��i�&owk�~�j� �7���v��n�>(Ky���)�ңŅ&5w?sG�� ++z�9���NgAA�����w��7�|366v�֭%%%&�i ������Y�f���#G�|��wW�\��_�={vҤI�ڵ�8qb˖-�ԩ#"�<W��wީ[��7 �S������$�/_��;�Ȳe˼�{yyy����l��ݻoݺ�b��?>66��W^1�L.\>|x]'N�X�ƛN�2E1RTT4{�lٸq�z血�� ,_�|߾}-Z�PU���411qԨQ"���Sa�uM�� ++u���s��&&&����;w.�UY�xq�5����q��V�������}��wR���z�~��k�>��˖-���[�j������[n�e�̙.\ضm[�>}fϞ=y��U�V~��C�mժ��]�5��}]���������;�ĉ�}�ٮ]�������g�����`~)W���3k�,}Ƨ_S���74h��G�رc�����A�}���7>u���CS�NMII�������>�lxx�7�������c1./U�P=���ޗ�={��3g����ꫯ~��'���ݺu�[��A�����th��t:��A�v��v�(Jؑ�bq���d*no4m6��dRUU���H͘1cԨQ{���)S�>|���{���ٳgxx����z���~�b�̝;��r�/�ʿ�ԩ��������M�6o�����СC�r��N}vݍ7���K"ҽ{��_����"r�ҥ���#��v^������z+11166�U�V˗/߹s��>����V�c���T222���SSS;t萒�r��ɂ�����O>��СCݺu��e�X.�S��QY5j�())�~�/]�Ta�iݺ�/�0|�p�۽lٲ�Eu��mذarr�_���[����ÇSRR���D���ڵk��/���M�6]^A_ ț�U�V-=mWQ����:u�4m�tݺu���5k�LMM�N�w��p_W���ܹ�y���?k�`���;wnڴ�]�v�7��^`W�/�r����&M8p�ޙ���u��#u�:u����Y3dȐ�;���4hЬY���{ذa+W��l�����{�<���W����2D���G BO�w�p,K���ymg�W�DK�ZJN�AQԋ�֤�Rd9=�SN���g����\c��Q���9!��w_�~�Ο?_�nݤ�����^xA���Μ9�j�&%%����۷����߫effz{0D��p�I�f͚����k�Θ1cڴi7�|sjjj����R����+�ddd$&&v�ڵw�ޝ;wNKK�U�VM�>]�x��W_}U?�C��:!={��������<��c�Q��!!!�u��˗/��J�Y�fӦM������{<�q��]����\y 40�͚5����}��>����;��'O�<eʔ;�#>>�B}�N=�۾}{��F��ǥ�֟����Y��C�vff�����y�իW�^��N�a�fΜ)"YYY�������|?���Sᾮ�)--MKK+�P�>�G�iӦ˧��K��b������>��3�� � ++E�ӄ�Vkzz��DD�������ޙ֮r�+f�\�&O�\���O>پ}�+w����������O����{�������*c�L����p8����)1��ԫ�{.�ih�[���ߤ��UUϞTU�`08�vv�&M��9sf�رO=�T�&M��[�n�3gμy�M�&"-[�lҤ�ѣG?����>�죏>��oF��=�ڵkcbb�/�"##��������¼+(s�� �IDAT����t�b0�O�."�\����z߈����fff���3///''��۶m�>Ŗ�̟?�Y�f3f�HLL3f���po�{�~��w_{���o�=88�СC����o��������j6�������� ++{���5bĈ���?���M�5jԶm۟�ܷo�E�͝;�����%%%%%%�֭3�)))�g͚5�I'����ĉ��Y,�.?~�F�����+{�ڵkoܸ�f���=�����ٳf�ҟ����ˇ5~�嗩��z�gjj�]����v����r��p_W���ݳ�?�E�Y,��;�ٳg۶m��R�G�R�+..�4iҖ-[����>}ZD����իw�ϧF��_����_<���qqq+W����.�>��������-Z����999'O����X�b�|��;��3f�Y����犕�F��l6����㸪c��Y��)��r:��mEQ�Ng��3��xL�zN�SD���t8���W�B���5a^�z�w�}��ãF�2�Ç_�hQ�6m����^z�����{�}�g�z����F��l6���j�<���\>��ʕ+O�:���/�ܹSDΜ9���>q�Ĥ���������c٣��bbb���kԨq��?�"##.\�����矏���۷���hӦMZZ�ԩSKJJ8t�P��RaOU7���|�ɷ�~[�J�3g�U�o2�L�&M>|���$"z�ܨQ��;.^�866��~�Q����-"��~��ʸ���cZZڢE�^{���C����|��h۶��ŋ������###�����ʟMx�p�B�Ͽ��/ӦM�7o�ȑ#SRR�{g�����s_���b)���S�N��βe�ڷo�lٲ_��|���f͚-[�H��#F�����|��>�/e�ȑ�}�١C��t���{�U��ڵ�ύ��Ս��mݢE�n���?����?�|����?�X�����<r䈦i�۷]�!22rѢE���w��w_�)U��\*( ++4��,}z6�M%��}���7���8����v��Pb�'iY����n�4�l6[,����x6J���sÇ����EEE�ҥ˔)Srss=O���?��S}����?w�����_�t����7�|sPPиq㲳��y睄�7nܦM�TU]�v��ݻq!�zJ�0d��� >�য়~��K/͟?�����?�={���iڐ!C֬Y�} Ya8�������p�^�>���i��\���T+ӧO���/�ߧO�Y�f�H^^ސ!CF�}�ȑ�;wN�<���n ++ q:�������EEE]�t�{۫���1�ʩ��S��jr�淦t�!��>���b�x<n����hNg朽z����q:�.���t���)[�l��'����ŋ����Y�fmٲ�w���G�����noҤI�k���^x���/]�V�V-o��ϩ��ٳg���.l۶�ŋ�͛y� ���{"R�v�^x�;�|8֮]��d*c����!(�~��j�q�����W������W���� 1b�����믿���w�y��ٳ���AAAaaa��!UJ~a�UFd������_�ʏZ�hɂ�ߺu��`��RU�h4z<�azL�8��N��m��Q#�?P���ъ��UU ������n��z\���N�Q������VU�AY��>�z�����=��r%$&�ڹ���se�����L&=D_F��֍O萒ҽ[�{�X�m�5���� "���GD W����MG��U���={v�ٛw���n�D�8�[@@@l��[om�-��������NA��7��T+v�������_�r�������)zB�����A�����"����W!������ ����_�̍������ ����W�V�-����P����EQ�q[���� ++M#����o�A����iϚ�@�V������� DUI�/�K���߄�GT=!����M~a�^�/����=!������ ����_������+�����~E�����B�����A�����"����G ++A������}RPP0r��.\�NVV֔)S,�ϯ������ ��v:t��v_�����Ϝ9�������ib��yΜ9�t:�킂����vt�z��}����G�.T۶m+�g�ܹ)))>iҍ��ɓG�4hPU7����]Q ++�J�F���3f������q��+V��X,������7�x�����*Ԍ�� �dc�֏?��u��s��5k֬O�>ޢ}���]�V�nذ�#D��plݺ��~p�\-Z��ڵk@@� 322E kٲe�=L&�~�����ׯ߬Y������u��0`�����o����7�ܫW��ڱcǎ;������S�^=�4������/((hРA�=�������{�=1�L���ݺukР��� b���Պ���MO��̜9�[�n"���5p���[������Ν;�z�- �W���i3g�|衇bcc�v��pM�bbb����)����7�t��%,,lݺu۶m�ٳ���f�5k��;�UUE���,Z�(88����2������˫S����������l�%K��������ӻw�i��`�<`[�~��j���رc{��1b��f���ǎ�y�����{GDDddd�8q�C�z���~ZQ����ŋ?��3��(�����|�x]�p�h4����Ço߾��^x��/^\����s��Z���4j�(}�iӦ�N�*_j�Z�����ý{��Ҋ��F�i4E$!!�[d6����d2y�������X�)%%����f��?[nnn�֭+�*33�Q�F�j��ƍ=z�iӦ۶m;v���v����+��7����!�?b�ݻ��r-X�ࡇ�PTVV6s���f͚O?���O?-"����'O�����{��S�~��G�O��b�=zt]qqq���������nԨ��ht��z8a4����7nܸQD"##�7o���ĉ�� ++JKKׯ_?dȐ#G�T(���ٵkWqq���8{�lPPPnnnHH��������(��W_�7���g0|�y������� ��ŋ˗/;v���Q>�p�\����������?��Í5�2eJ�.���?����]!}�s��;v۾}��~8q�D�ݮ�@�������-"�ڵ�s<�v�ڱcG�ݾ{���;VD���x��+^���?oժU�Z�\.���N��;��u��999�gώ��7��!!!�C/�4mƌ"�DŽ"2y�dEQ���-[ٴi�?�S��@��� ��tΜ9�~���G�n�c�=�'?�ȇ~�m�6}��ŋ].���;w�ԩS����j�Z����7@(����r��|����h}�y���~���b���߷o��i���S�N��o����:&�Iպu��۷[�V��b4###/�bAAAZZ���ڵK��p8� ����;���;Edy5k��,,,,)) �:ujFFƪU��g4��� 4���&���o�,�x��s�=w�����{�d2�o�~ʔ)�>��1c� ++mڴ�?�ʕ+Ed���6m��}�?a�q]_�;�lٲ;�322���8$$$--�n�7o�|Æ ��rK@@��]�CCC۴i�k�>��]�v���;w��8�N��f�����t�С-Z�.��n�;��QVV>u�T�h���f��W�^V������ѣ��iǎkܸ�ɓ'�Vk�&MC�֭?���ݻ����o�f�)�r� S�N�}��������P=�,9p���?���;�ԭ[W�s��w?~�;YSrr���o��o���������QQQ�jI*..^�l��iީx�x�.X,�[n��~��6l���kԨѐ!CD�l6�3�o��裏<O�F��cնlٲe˖��Ф����_D��������=zT�D�ȑ#�F��_�~�������,����?n9!!aĈz��]wݵk/�����811Qo�nƌ��V�Z}��mܸ��i������:!ÇOII �P�Oѻb� ++���������9r��� ��qJKK�͛7q�DE��?ֵ�uB����_�"""}����+.4a�X ++���D��{���ӧO�jՊ ++���7�?p�o��f֬Y5j�7n�����w�uWpp�����5�Ɛ��\~<���p���p,�ө�*kJ�w`8��@���X�%)������Ԫn������ ����_������+�����~E�����B��������-s��Ρ�텞N�^��5|i�O��PU�h0���FGE�*�*���|�A��~x,�y��������8<���|��Z'�NU7���7^r����+!/6{�g��Z�:f%��gõ@UU����P�m����F)(*5��n�����n�������0����_������+�����~E�����B�����A�����"����? ++A����?#����W!������ ����_������+�����~E�����B�����A������C�M���������>���^{��+i�6mڴ�g��fdd̙3�f�]�l�~��/�xŢS�N�߿�������g�Bn���իW�8q��"M�V�XQVV�����o۶��t���xwV�nݺ+���ٳ�Ǐ?u���ŋ�^�����}���� ����lT*s����aÆ]����˛4i��xn��f};33�{��x<z����5kք���;w�_�~W?ۚ5k�ԩ#"�/���>|xiii� ++'O�|ꩧ���c4+qgע�'O9rdРAU�� ��&����.����ׯ��'���ŋ�m�ַo���@ٴiS�V�bccE$>>������DD.\��(ʤI�ڴi3gΜ���q��=��AAA�s.Y�$22��p(�b2��N��`PU���x�Сz�)S������Ɋ�DEE�oR����233ׯ_�r�z��٢E��-\��aÆ�;w�4m�ʕV�u�СK�,���P%,,�e˖=z�0�L��?��s�}�݁�֭;`���h���۶m���0`@͚5�~]M�8������ ���#:::++�����߭[� ����@�� $((�aÆV�uƌ���M�41�.�+++��>�9sfÆ Edݺu���Dd�����YYY)))��+��RPP��C����M�6�nݺcƌY�`Azz�SO=�����������nݺ�oφ *S���f[�t�������,X� ��R$"�7o>���ѣ ���������l�%K��������IOO���i�!$$�{xff�;F�q��٥K�N�0AUի\w������{�������8q�D���O?���(iii�/~�g��������MNH~~��)S���^|�E}��h|���t�2f̘�����{���'"˗/߷o_ӦM�Ν�f����|�A�Tf�y��yyy�?�|zz�w�!"�{�.--�ӟ��w���c��[�v�7�|���j�8q�V�Z�5���o֬�ѣGM�{���?l�0ow��l4�L�`#777666((�`0���$$$x�p���6m�����t�M�#;;�*�-((ضm�����6mZ�v��n����Hpp�~����o<�����1G���O���}뭷TU�4m�ĉ��w_YYل ,X��lEEE��u��-"��]ddd�f�F�ٶm�9s��G������X�|��I�|�����/�#""���*/�WXX��߈������Ţ���s��%&&FDDx+oܸq�ƍ"ټys}�'��\�t)>>^DE���,**��usssCBBjժ%"�����xs3^}�U}�_�~��i������A9iҤ�m���W_}u����۷OOOߵk�����t��qÆ ���999zOȘ1c�L��[RR�MxUU���G�1h� �Ǔ���-���9s�����h�k��(�eR4MS��rss�y���i�F�ٵk;���ݻw/X�`�ر"��������^�I�C��5M�1c�����=���z�ɓ'+�����lٲ��ȦM�V�3������`�.]���<��[o�5w��ٳg>\O��3��G"2��y��:tH���m��QQQw�}��I�������_~��͛/]����k +..�fiW����cǎ��EEEz^�ՋRRRڵkg6�[פI�G�d2��Z�n�}�v��j�X�Fcdd��]\\,"����v�ucccKJJ��¦N�����j�*o���@��ܠA���l�������� 0`@hh�<���3f̘ ++E/��������7oްaC�z�D��_y��͛���+"��L�>���X�n��|����W�@D$""""""<<ܷ��;$%%���:u*''�رc-Z��Z��W�.))��H?$44TDZ�jU�v����Z��t:m6[aa�}���ヂ�N�<�=��r���9��QVV�v����<x���C���愄��\7..�u��}���ӧϟ?��?����f�X233O�:U�n]�}v����|�v\VVV�v�={�t���j��\��-lڴ������^����ݫW/�Y���v�c6lݺu.�k���QQQ���YYY��Q��±����;wn�֭Ed˖-[�l MJJ����E$==]�D��ѣ+W�Է�92jԨ����v�m.:t���v��*뮻v����_'&&2�ی3f�Z�j��۷q��~�����P��`�B��bٱcnj3���y䑥K�<x𩧞�ٳ�7ߺ�b��7n�+��ҭ[�g�}6::��'��)/''���_~���E]^]�|�����WX$$$�رcÆ ��+,--�7o�ĉ�'��X����Zq�<F��3�'>��5k����|���f��C��W��3gδi�z��q�=�$''�Y�.�k���ӦM�<yr���E䩧�7n�c�=���/�����ӧ�%*����O�q\"���W��ҥK��S7����ӧ[�ju#�����-t���������)))�F���{�0`��C��n�Z�~����aÆu�ԩ��xժU���3Aծ]{y���=گ_��?���W�Q��UJ[���<�F�^699999��[�����RP\j6���z��k��f2�n�H�zb8��@��py�&e�'Ê.O ���p��������pu!������ ����_������+�����~�z<ZU����@5b�l��x��K�J]n����I�P�TU5��!��QѪJw���|��d�f�l�ʟ�����8��6k��:U�����Px� �����|����_�_j)u��u�PU�h4��FGEWu[���p�Q.�U�T_���U��������Q+�������9!������ ����_��Tu����T'�FN����?b8�����R�����O������+�����~�29����R�����~�p,����~E�����B�����A�����2�p��²�"���S� ++�́a�Q!��U����ܘ���+;�DqI~�9�d ++��)Q5�ʊ��s��c㓪�-����E|�d�(���hڡ��5⇓��sN������T���*��7m��' �5�Y��E��ʊ��!����Ѩ�� )--�A[p� .)+��V����F�ٱy 7$�)�i����sL������T_͎�����=!�����G!����g>�����~=U�C������Z� ++����70*Je��*++*���5������DTu+���p�Q+����ި������)�ʧ��������Ml����}���������j$������#Us��� �����U|�������Z�ٱ������S������������~�j�������~5UU�����?������+U<��n����jC���b�eeE��b��ה�������n���n4�� '��FnT������c�+ ����'-µ#+�XU7���7���������*L�����U# ++����?�Z���bG�|�� �IDAT������ ����GA����RD�4rB�������� ����?b8����?�D�#�����(b�JG!eeE��b��ה�������n���n0�*>HL�3�Fſ,���|�X�S�������MlZ�Sᚒ�}��������� +++�����E%����O*k����'��/���TDD�)��#E�hnM<�eQ4�QQTŠ��*�"��G�D4M4Q4ES�� ���}7�����h�&���Y�����N���ܪ��=.Q��������q����ͣfP�F�lVͪfp���q�x��&�*�[<�(����xTEuzMSŭ�DĠܚ[����?�T4�#n�h���84�L�ɩ9DĨ�]���p�D4�btjN1*&���<EQ5�S�Ԥ�n�(b�i�Y phv1)&�Ǯ�fT�.�."�b��-v���*�!H 1��!nq�?g��1�8_}+����/E4$��7�P_� H<o����W���!�p��DQ�Gs��C�h��i�Ek:/��c�����Zu��gD$6��y��a����QDBMQŎ|1�n�~]�jrk.%�Y�*�����|�j�a�-r^R5�]�.�05��S$"Aj��]*�bV��!"�\a���<A� ��fP!�H��D4 7F���4�pcd��PQ�PcD��XQ$P ���D$@ �{�"�~�z�ɥ�TM1������UD����L߰y�4� 5�汊���pۥ\�$��jvx�"�Y=6 2��Ԇ`��""j�]�)"&%Щ�E� F��T1�(��h��-nUz���<V��6*���W���������ٱ���O�H ++I�}ghr���(�����&?�fA�����-�[խ�����IQ5�B������"jU7���@���O��������V6-�lt:�>i �)�- �|�������Z���АH�����csXC�#�������� '$4$"<��'�U�T�v�pbOTD��������o��M�O��9���w��|U5�䜨*6w����N�kT�m��� H�p� 8��s���.�."v�����à�ݚ��1\6�KSD_ݥ�Q��Z j��aT�\��� J�~*U1x�_�iyt��nU�*�Q ry�ox��T�GMQ�˦*���O�4(&�&"6�����ͨ��U7���k5p]���c��B�������B~ap���[�� ���Zq�ݬ�����UX1����������#zB������*�R�m����P��������B������/! ++�������������D� ++����D�z��x��\�������7��)zE�4�Wݸ"�������~y�^�A�? �����������Y�����DQE�������?t������+�����~E�����X�����_������B�����A�����R���������($�����MD�4�/�S�X�� ++��4����N�����15M�Y�� ++�����6����J�:~_����&<>��� ���o�(�����%����R��������q�U�:������&���������b�������W-V����>��BN����Q���������_\1����|JQE�r8���Ռ��9���ݲe�{x<� &>|�B������*))�pHQQы/�x��E?������I1�Zٜ��s��7_��w�}(";v����RSSE�СC۷o;vl^^�������HY�d����r����o���/���t�[�nܸq������4��f������&M�����2���P�3g��������+V<�裊�x<��K��ȃ>����ƮY��l6�Ș1cƏ�����BCC���+\�����%RPP "gϞu�������5j����������W�c���%$$��={Λ7/))��ѣӦM����o��;w�\��;~������6l6l��ɓ�N�O<ѿ=�`���͛7�<�ꫯ�M�V~ϣ�>��.������v}u�իW�ر���+((X�bE���m6[BB����f�={����o����/[��iӦ͞=;99�ȑ#�������<x���?/"/^�ݻ��u����Ed�ܹ�.������!�۷��WUUmԨQjjꫯ�ڭ[�ƍ{+|��ǎ{ꩧDd֬Yu�֭W�^XX���㣢�>��o���xTU}���w�ڥ��ꫯ^{�5}��;��n�����hF_�U�����Ͼ��K#G��ԩS���?������ ++]�vMNN^�lY�5�t�R\\�f͚Y�f�~��'N��6mڈ#Z�h����n����:u����aÆM�2�U�V"�v�����{ϹbŊ+Vx�,��>f���������YO���q�s���TeԨQk�g��5l�077�ȑ#��ߗ,Y2{��&M�L�:�S�NV�uŊ&L=z�#�Vk�Z�j-"%%%�����ɉ��"���w�ށ��QQQu�����?~��ŋCCC�Ґ������_1�p�������Ͽ���� JOO�5k�2D/ݷo��ɓ�V�#�<ҧO�ٳg?��&L�ޱc����j�F/�O������,++����9b6��t�r� 5j�h�BQ|Գ�������'��/�:t��j]�j��_����Ϟ=;%%E/���Æ KMMmڴi@@�>��~-"7n<z��{���FEE�Gmݺ��{�1�L�������,�=�����y�_�u�Ν�@����k�ς�Ç���˗/WUuŊ���,,,<w�^��n����4M;}���-[z��-"111111"�Ws8��_�8qb��K�,�^��ٳ�B��f͚ :�駟>w��{��{������T_��7�x���6l��'���� x衇:t�W�����OF�u��~���v�]D���/^�x�����b�����UU������x�ƎۤI���v����<��'^m۶����x<V��W��������lv�Y�f�r�-"R�f�>��y��.]*--���QUUU�]�vmܸqРA���zBB�>˛1"?�m�������/77w�С<�����Ed���f���]�6l�PD���>�v��/��r�ȑ�������x�^�z5k�,...""�f͚����������EQ����!A�9�����/^ܲe�������1cƄ��:��Gu����[j�X^��ɓ'�����s��ɡC��\�ӧO'%%:t�u��z岲���<��P�N=��СC�������T=,)++;z��ѣG322~��dzgϾ���]�t�̭������ ����2��A��x<EQ���i��7�����j�b��&1]U}�[��������E� x����Pm)���W+������4�*A����?�4M2+������BN�����b8�����QDT�Ւ������K4�������������_1;�����R&�����G*��������&�h��n����jCa�������:!�����G�*�Jw8�0���@u��� ++-c�s��-��l��e���mN���a��f{�����{v����G�\X�������_|�g�6�����(�}�Xa�qw�z����=%y��<ϙ���w�jb�����g͚��3--M�x�'j֬y�ܹ������#G�$%%���Ç�u��6����7E1�$'$�;m��}n���v�@���!���O>��g�}ֿ�����y��َ;����Ȳe����Ӽys�rAAAYYY�ڵ+�f\��ɓG�4hPU7���70_�8,Z�z�U�;4MK_o�L2�'���/v��)"���?ЬY����K�.%%%?~���oW�+�������{�t�ܹW�^����Hff����].WϞ=[�hQ�����_}���f�رc�N�Dd� 6�ܹ��i+W��Z�C�]�dIFF��(aaa-[��ѣ��d�I�&UpW����>1V�$��]�Ga�H�[E���6��C���v���n�Ν����}��#F���u��!==�~��{���ݻ�#M�v��3d�Y�zu�z�RRR*��Ͷt����-X� ...**J/*++[�|��#���>���������{ܼy����G�m0D$555%%�f�-Y�$(((55UD<Ozzz��ݫ�����Pmh�B.�tW�c ++R��(�K'�� $44�h4�Htt��-[�^ٷo��|����q�=�c��Ǐgff�HXXX@@�ŋ{�쩏ڪ&N�8Q�V�F��H�f͎=��x���i�'444::�f͚N��{�{�����#��{�fspp���L���}gnnnlllPPPII�ڵk����իקO���h��$���nt>� ��g���05�����v��63����=嫕w����n�I��7o^۶mo����l6W��w��&M����fee����l��RXX�������������v��m��͛7w�\ 4������;w.111""�[y�ƍ7n���Ho�͉'��;v�L���ǟ={������>�(��jv,�Ʃ��:��5�m@�~!��$""�'++KD>�����lUU-KIII�F�ԟ\>Wo�.]z��բE���8q"11��="+���X4M+��TZZ��?��������sss�뮂���z+w����瞛8qb˖-,X��LKK��X6l����w�^}���� ���Ճ�i>����yD�iվ����pE�S�A�w�lEo5�!�W�>t萈���]�ׯ�������:mڴѧir�ݧN�r8u�֭U���dڼysNNN��Z�Add�c��������XoQZZZBBBrrrrr�_|�w���o�]DRRRڵkg6�[פI�(�������֭[o߾�j�Z,��)"�77nܡC��̙s�}��3#������b��I��{�^���bMs��݂"K���:u�4a�iܸ����ǎ���_��S�80&&f�ԩ� ��l���+W�\�x���ҏ���jڴiqq�wQ�������w�ԩ���cǎ�h��j��^����$((H�a���������lz�L�V�j���_�;�N��f+,,ܷo_|||PP�ɓ'�sm����099911Q������!�$�3����N�e/�l�_��^���T�$���jժe��w� 6�L��Ǐ7m���o�m߾������h4�v�mm۶����,))9s�����ήn/�� �n�:��5p�������¬�,�՚��\ZZ�h�"��y�M7u�ܹ±����;wn�֭Ed˖-[�l MJJ����E$==�o߾ޫ�[��ҥKM�4���[�|������)"Jޅ�!�����b�WN/Q��e��l��ӧ?�䓑��6�---m۶m�a�ĉ�9�JKK��3f4(>>~���"R�n�}���5���$�>�����͛8q��s���>B���Մ�f��p,����r��Pq:+�Y���3;i�VTT���s��%��R�^����y��y3���{�ԩ�s�Z,�����ѣA����;z��On�:;}�t�V��$��@5��X�ZM��A��]�N���x�#�I��vF�B�^.\���6l�h�"��S�n�|�N�:N�s��ݟ�y|||XX��������त�~����}�ݷu�V=�����Wu+���P=h�o�c�������0���Z�Xm��>���p�R�g�������@������"����W!�����G�4�������(�*,Q����_4ͣ�������U�)z�����BN�����b�B������}x2�Rfܽ�p☒_ "Zt��qS�j�!W�_ZZZPP���p�̙���zȐ!F�1--�M�6z�۽}��6mڄ�����ݻCBBZ�l)"v����>�ׯ_�5|x�����X����1��Ξe�v�z��+�z���-��g�ӯxȱcǖ.]*"EEE���EEEk=|��^AU�s��-[���r�H@@�� �����EDD��������BQT�̍eHO�d��_�{�'+��ddd4m�TU����5j��ӷoߵk����(�Z�[�l�X,qqq���G��t�Ҷm�ڵkW\\�1��wN�<�駟Vu+���p#SD���MW,e�5�^-�D��k>�ի[~\VII�?�p���_�p!;;;<<� "R�n�V�Z�l6��i2���^�Ͷs�έ[����)��o���o�{����J��u$33s���.��gϞ-Z�(_t�ȑ���_�p�駟��,\��aÆ�;w�4m�ʕV�u�СK�,���P%,,�e˖=z�0�Lz��Ǐ7i��߷����D�X�)z��w�} �*"���h����>�a7������[+--��v����=o���w{����<�HBB��$&&�HRRR�=Ddǎ'O�1bD%�}=��lK�.<xpPPЂ��⢢�����EDD�\�7o>���ѣ ���������l�%K��������IOO������>d���������ʐ�Ҽ��\2b�,���N+��i���o6�L.�8q�� ;v��ꫯD�O����^͝8q�V�Z�5�f͚=z�S�N����d��|��� ++G�ݻWꂂ��=f�988XDL&SH���rssccc���JJJ֮]���U�^�>}�DGG������Pm+�V�>��O��,۾�#�Q2b�,|_\������x�P8p@DfΜ�-���?~��`hӦ��k��bܸ�;��~���M��+ˇ�ر�XqT;���l�p�:A'i�ԁ�"�K_�V��i-Zu-$dY�#eU�b˒%YZ�����.�9��>��k�ZIK����$^��������̆ ^{�5"��O~R����g�y桇Zh�d2Yl�hkkK$�wdd����<�۷o߾}����������/�p�B��C����K/ �������PT��X%]��8����_&bz���̳���V��,����N���������#�z����|��P( ++�t]'��^z)��7�xcxx����v{{;�!�0sq �R�o�kxx��g�}��N�8Q��x���<�eY�~�W^|�E"�����w�KD��sϮ]��9�e�$!����PgL�h�ݱT�̰��1z���y3+��5����իGJ�w���}pppŊR�����-�����ݺ�wvv��H�����������Q*�*2��~x˖-O?��;3�f��#����6o�<::��������n���?����/~�ٝ������H,|L��~c�")I�y7{��������կ>��s���ٳg_��-[��ǣ�fY�o��v��^x��;w�����֭�t����йs����\.�k��i)e&�1M3��m���D""z��V�\����B�qL�L&�G�]�zu0�x�bq��Ç'��M�6��� 5���������n!w�V��*&���OU�(��ݺ�|I~��g�y&?���GݱcGGG�SO=Us/CCC�w�,����~ x���_~���gvj�@�;��Ξ={\�����ёL&���r���8?�������?}��ǫ��W��_��7o&�8p ��[����'�3g�<���Ž�ٳ'�oذak�Y����X(E<6��,'���9�l}����h":p������c�{{{�~�m)�i�[�nݾ}{~�&":~���o��i�&�4m����F�>��K�.=��s����~�����72Ȥ������ZA&��OBDڙ3�7ߘ��t�����eyBD���7n����=�H$�m۶m۶˗/�;��nذa˖-J�;v<��ǎ�,��[�l���R��kYV2�������pkN�<9<<��O6e�HB����ZJ=�"�lF?|X�p.?�����ot�n-Pz�ݻw���|�8�ڶ�s��;vl۶m��Î�l߾�4�'N�:u*�Lf2���0�0�nݺm۶��M�$�����d2Y�'�$!u���R�녥 ++I���@K�d��>2��afd �����K�h�9n������ĜSZ�������I�����4�hv�������J������h,&����IDATA��ٱ�����`�Q�������������� ������ �0;�����4������h L��������L�f������ф�xN�����4�RJ�cqәd&��m��eB��|�h�#�5;����X�Qݒ���S� �/h�z� M�ɤ��X��g��f�����K �+ ���M߿���R|��xt`�"������/!XЂǥ�������{��#$���̺/��&2�T�����%E)��q��t���#h�ܤ���j� ++�Cәd�������M��CK�m��x]��9�;��*��c������/�\��XԤGϊ�����CK,j�#U�7����@�1�hv�d�+��� �����e(��)��y6K������4ZBZ�k+������ht��L�yv�������֠�D��\��A��Y�����L�/��L&��N-�h ++�^����kW��O�dR�p[S��������e`:5�X)�H%�mb8�����Pg�Y_x���؝=�4��V�|��gt��,�Ѫ�� �kJT����������X��Ă]cB������R�]nZ���Bg�䐄����@#0V��\�XS$�3� ++�������ǭ̵���F�����hf��Һ����nV6;����h !�̵���FZB�����Q0;VK��Jh$4r��t����hF�Ҝ�*t��������(���\s�%�nv(�����2���S��B#-!�����(��ɤ�٩�D f�W�?k��*��w�D�Őɤ��f�����Kק;:t-V�,Q�G���3����u�D��K �c�p�Ξ�/ ++쒓��b̔3�����:+��� �kV`�������a��/xcg�fG� ��X3���ţB������-!KI�aW�j�}-qX\��^�p%0K/����4JK�m�87�<�U��]S c& ��y�������L:����J�L�4;�4��7�ZM�����ZVX⚤����C\��V�)39���� !���%#�F���e'[☸�b��n8�߬���͎����ZZBJ��R����L�%n�]�HP��dDžFN�����@��sB����IBS1�/��=Sh��Z����������۴�� ����sz|'!Jѥ�s�7��NF ��v��B!/�av,����h�F'!���� � 7C..5?k~�-�1!�I��93�A�Me�)��ꁐ;ac`:����4�ף;V&�Jg�np�}+��~�7f�r��ę؊����tkrSk��1���k��xq����������y�L.�p�l=��f�lyw���� 2�T8�v;�����VT����[w3�g ++�3q�}��髡��!i7���3�k~���zΔє0��iA険��� ++�a/���|Q;.���qq�a������/|��p8����8�}9�v/��?q���زPGE�1�;3��}��{�0\>~�9�py!�ͷvY�6�>���1�]����Y���:[�\��"�O�p$W$�Nb����,�������6;����� ��*q�-�|U6!][�#�ҜAᙸ�fZ�tX��(3)� ��x��{��]K��1Oxz�o%X#Ͼ�;�����L50 ���9E��/�ʣѳ����3n &�N\mΰ�l\��$D�Qz��r�d�'?��SC^ �DDL�n1t�zy�gS��{Z@{Z ��L�������h���ι�����J>��)�=#�Q��,]eN5�V8=! !<���+<���f�t�o�F�o���?:g�٤i��f=�GD��Rµ�������m'�Q�@����Ѳ}1���߶)��RF���Mi�M*���P.u��+�/&�o�?�39�y6������Ru��h������ �R��+b�d��;F$�R�Q.ZB�����S�T#�;���%�/\���:9���عR~b9q��I�k+�Q�cB�T� ?7c���5Z��ܻ���gO�ֺ��s�m��A:9:����c�u����p��]�S|��v5\����?�R���;��Q!����p�)��sBn��q'�Vc�Il����%4w��'.�HB\��i%t������(%K�Z�\B�����g�m� �����.�X8���Z������R��:�Խ|��X� �Bm�k]����i�$ie�j�:�����OTO��Z��%�v�`���3i������I������55n�u?2��,�:ie�*�Uq���9�$)I���SB#b�c�v����@;�4i>�N*�W�;�O��*�ב�����g���R�]��������x�����JR�'~��G��ڲ�Z�C'��cΊ�t"����֗*;"�Ԑ�T'<�n1v�[�����8�NNF�17,Ħ��n�1%Ѣ������ ��?���d2��%%������i_-����6�R���XbDx��*e�_1�Z,T��d�wv������̟���Z��z�ӹIy�uۜ����`Q��h:�'���{w���ܽN�,+����b���g��������;�lB>�B�|l��I��^;�B�:ٜ��z�C4���\=dw�S�r:֊��6ß��W���i��� ++�Ԡ�j=$�Z;�������&��xN�,Śb����:��ض�v�y����n���sB"�v�ʕ/��m��Oٳ{������P����r�ri������#cVBD��I�K�;D�Mȱ������zw[C'��37=R{��5�ȫV��b�gu_����T���+��:�rε��y��o��_3�Ci&.��Z=� ++�t�+�l":���}ܱV;��R������#ު��B��=Z��_��9��]]�ڄ5-?�a}��e�����1;5,'��/T#�4�v�v��\n�t4��d�Myz���-��mg�v.j��j������B)�G?��ϸ�MD��,���ݹ��>�wSp{�lg_���э��<=.GNy��L ��>/�|�6 _���:�;{�75�������]��&��k&��b?%Ϣ�^���k�mA��ک?���\hy�Xl�;�5_ԅ�G_5�1Ᏺ?"B�Bӹ�Mk����L �`����y�k�8~�/���)�w�}G��e/��:�aAF����?�_���%k�� ++�Rl�0�,4���>t� ��Sݕ+Ohd��?8B�ɫ�����_n��]�m4;k���kN�i��vS�cm����UsU�^��]~������(�c���P�V��40t155���Z���I�V�B��V�c��-7�H�G��t���4���k�іj�n6� ++��,k��v'�@0�;�[R�\{�/gZ����g;�¹DPk#=&=����j����C��2ݳ��.��6�3�FVR�n�Y��!��<6\�� e��.�s�/v�g�)ݳDpy�i䙁@צT�|,�lΑ�Δn�9�+��]�L���Y�tIW��y3=ɼ��B�-?ByB��t%k��\2��}β��F?H�J�^B�ɴh?MO#)���V�U�^�^����������t��%!D�ɤ���QN��)"��ДCD� U}�-Y�#"ɺP.�"�i"rٯ+��2ZG؛$"� ]9D$I��>�i֣�k=24r��e��l"�E�'�D䈀!M"�XהKDU==�"fR�%8"h�9�oH�|U���w�,�X�� ++5�]�|5��5kꊀ.��25-����AC�������o�8Ƿ��������7 �HB����Z��Xbֿ�������6�b�S������� &�,�����E)U���������8A�<������:c����@# ��������Q���Ό�������'1�Q��7�*����ܔyZB�� )\$����pS�i af���j�������`��y�7� d ����p��x��1�����@���S��H��a�����@��MM��jv������*���[���av#�����h������2��gզ��4;hQ�a4;����h�D�ɡ��������Y���������R�<���HO =~�����������s���];'4�I#*4��������_�"�� ��X����-@�������B��4M�XMJ)V}���s���>�B! ���Xڔt��~��)�33M�XɊ=�f]�<0�?;�ttt|v��M"�HB�����.���pxo:1�IO�Mc����`O:����VtĞ|�O<���V�X�#"fV���������Ј+ʯ,팔"TXʤj�� ++�͉���TDDJ���0��(�굪��("ffb.t]+V~��ffVJ)%�� ++y�/VfV��z��5�o!~E{)-������*��j����b�Zv�vZ�K.�[Q(����pPK�Ŭ�[*%�R2�UCU�d&�«|�]~і���D�gNS�%UyA�9#J�X>G�Kt~#)K[.)�����~�+E�l���3K�)U(��E8+��K�(��/�*^X��.U�u~��0��=(�*P�|E,8_Z���b�\��}u��T�/����hTV�y�1��k��6����3�P���:s|��uvJ�!E��K)Y���8��Ry3� &.�����^��h��CQ�V����w�^V}m�&+�_8f�˪t��\��ϻ��o��7pYc&RRz��'���BJ�����LB0���UR����i搲���3�|�Ժ��1�|�R���TZ>)ů&��K��C^yr�LJ���&�m9��Gy�œ�_�#V�P�o��ˠl3����청T�����Z�(|�T=�j��J�q:Tu=�+�?���Ҋ0��g|��TU�/�5��U��)_����������j�3��V���a^g� ���g���F��wu\����Rs���Vd���o!U�7 ++�os���WgE!s�s���wV](�?�s�Z��\�����{�Pco��K���Z���P|�ce����"�e!�R���?�6ϳp�����IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/zh_CN/image/2.2.png b/data/ukui-system-monitor/zh_CN/image/2.2.png +index 0ab89fa..2e148f7 100644 +--- a/data/ukui-system-monitor/zh_CN/image/2.2.png ++++ b/data/ukui-system-monitor/zh_CN/image/2.2.png +@@ -1,23 +1,38 @@ + �PNG + +-��� IHDR�� ���Y����t_���� pHYs�������+���IDATx���g\�����la�VP�bŒxUb�]c�`�� &&�\��īO�h�^K���Ă��\�&h���LB��KQaa�����Őa%F���fΜ�=�,�3g�0� ����T�6t�����S�I�����I��/ +-��5�^�7� �hdX����J��㸆n�����$�z�������6X�U�ՈJ�� ����F�AH�Z2����[�bAN�z�����M>H��9 �>�3 �>H��9 ����<�$����������CN���09 ����<�$������������111���:�N�P������:99=�~��������@S� YYYgΜ �H�����ӧA2d�3��@5�I�P[� \�p!..��gϞ���������z��{���0���'33s���bN2���۶mS�T����߿�V�%"++��-[QNN��`�����H��۷o_�P"�4o�����۷>��Y�Je@@���w-�%;;����m۶f�fff* +-�'�9 �j� ���!!!���bI��͛7oޡC��G�Q�>}��>,X���lee���s��>|877��7��裏�h�ҥ�_x���ʫÇ߹s����><u�T�[SSS<�hѢZ��q���F���O���8p`�ԩ5�9 �j%777..�rH2���5jԮ]����k�����w��ͫW��������E�Ն��6,>>���|�ͩS����ݻ�K6nܸaÆ�;Y�j��b�2yʮ,�FdժU5���>X��F�DDu�@CGGǩS�����,[�WII���-Z�����I�P+111����C�������7&&��߿��dgg�Y����P�ѬY�&88���o������ӧ�������~��� [�l�����x�Ѹu��*�f͒���z|�ϝF���...S�Nݳgϸq��y�����Y�kq���Jzz���[ Z�l���^�N|||"""�/_�V�#""ƎKDÆ {�wT*u��y���������v�Z�V�����������O? 6̥�N�v�Z����P��ruu�4i��_�����!�П��������k��V���)�%%%���w��!�[�n�d2�V�P(LثW����]�vYXXDDDt��-;;{���#F��ҥKlll�n'�x1����߿���2$r�ԒB���ϯឲ���O�i������mۦ��������ё#G8�#�6m��0[�n�����/6m�doo?gΜ��Ԙ���۷���[⠇-ZlݺU*���q<7�g|R�U� U�r�Ԋ��[zzz 9)--�gQ�h4/^���� +- /�Q||��ӧ['��L��5jTII�Ν;'O����f͚ED3g�<~�xYY٢E��-[֢EWW8J��H�d�F��j ^n{��7�ٿ�� �f��$��__�C�u����Pn�NSy�H���jժN�:�T��?����|���⦇ь38�+//��w{��%n��do����s�~��%K�4���A��gmm��矷k.�����1yyy�xnܸqO�W�9 �j�����_>z��Q��D%�Nu��py{{GFF^�t)::��8����?�?���Ν;�u�9r���;�� 3f�0�_�|���ˉ�[�n���*��gϞo���{�r�4U)))���?~�����3((h߾}��U�9 �j�w��D�k�.__ߖ-[�����������oo�[�nu�ر�{�8���X�=z� 7n|�W|||Ξ={�ȑ��0[[[�����ʕ+��퓓�۴iӢE���ϯ[�."""--����u��۶m�s�r41Mf�R�LMM���0�5++K�T��]233���W�����sҤI{��0aB �J�I�P[�������;&&&66V�T*''���@�Zݱc�#G��=��Tݘ1c�r�����a�~��篾�^2m����ׯ��_�lٲ͛7�����A���]�bEpp�iӞ~9@cш�P�<X�sKj�.���S�Lqww�������bٚ�HBN�����dv2I77�ѣG���Ր�x������͵�� "�Nw��������H�DR\\�����w�i4///ggg�e���͛7��燇�7k�����>�H$Ì?�o߾�ׯ;v�ʕ+}}}����g���]�����Kj�\�<��q��̲��� �5A���,X2p�����C���߿O�>vvv)))�O�>u�ԕ+W"""Z�n}��A��,--7lذf�"����~�mq�<χ���P�������sC7���P���PQQ�qVVVD������`vޣ��B�%�N��j---+�B�T!'�'�$����u9 �>5��h����������`r����y�I�����!'ԇ�t_:4 |���~���\.o�&@S�@=CN�J�=PK,�������a�$�z��F����F�����˲r�\�TV~Z0���$�����p!�����<�$����������CN���09 ����<IC7�j��C������RDަ&f�4;;��[!ggg���841�I�X�CÔ|I9~��F�Q����z�Z�������?CI9� ��s�h4j4��n�|�6b �LC7������ ���I��$�<�����_������!'���������`r����y�I�����!'���������`r����y�I���ͬ}���z�p��ឌ��?:i���A��:RPP�����jO�<y��}AJKK�W���<|�paa��$**��ŋ�k����ķHLL�srrRSSͶD�۷o�<���O�����<k��`����ý�C����_�`�>m�Iw�=W���ۆi��bԱ���|�NF=]�vN��#�΅��������Υjꉹc\t��S��A>�o�]W0U�(--�����̼s�ΥK��?ީS�͛7O�6-""�o�IHHX�z���M�W���}��'~~~� 7n9rd�^�����o�ٿ�֭[]\\Ē_�uҤIYYYDq����>�L�TVV���������y�ڵ���?7o������vʔ)AAAu��xdffΞ=[&���osuu}R5�Dr�ܹ�����bIIIɧ�~j����0}�tKKK�bh\���.�Z�{��w�0�i\w���ca��|����Ok�G+�P+���ǒi�c�֒��k��O/;1Kߐ�+�-�"�0�+�v��+@r7_�6�Q� ��JoB'�_~U;�����Fv},]�'��Lj{�M��G��r�J��� ++��� IHDR��Q���k������ pHYs��������� �IDATx���y|Lg�7��9g2�l�ȞXD�% m����Zj�j�/�ml�~Ei����?mI-ER[�V� ++��Y �d! Y&���<#�rM2>�Μ����ǵF����S��g�Sw9� �����0A�9�E����0q�j2������w�����C�h��J�J���th��Ƃa�D"��,,,�,�P��4,<ϗ��k4��.�S�J�r��e��.�<��a)--�j��] ++�g"�J��������4 J��L�F�Q*���hP����JU�E��*� ++��AA�h@t:]}�n�/3� ���,YRTTT�QGGLj��>}�<�2��z��{��4 w�ޭ�"��A`��Ka�������]PP��͛�t�R�ѳg�Ο?��������ӧϝ;��ۻ�����>� 66����|��(ݸq#***55���L.��������-Z�x�111�z�rtt$������Ҍ��aÆI$��{�T*ϝ;kW++�:��/�������Z���&$$���yjEEE���{������;w�9s֯_���cؙ��<o���'i�C��FF��GEE?~|̘1S�N���-++����ׯߤI����N�������z":u�B� ��C�rg<�������������2�k��<�F��oo����Ϛ5+22RL����$w@��F&**�ʕ+۶m34��d�1cƼ��|�����q�{��+++ ��j���z��T*�_B���'O��q~���~�����:�B��O���'22r��ّ��:�� ++|����ˍ7~�嗯����Ҳ�!�\��g�������?:䅈.^����ED�N�j9 � �i�H$fff�iVVV�6\UYYy�ԩ�={���vN��7u��e����g�� ++|����KTT�رc |"kk�ѣG���˖-{�h۶m[�h���goo���{��qWWW"JJJ2���w����^����D㏁��M�6�����w��̨Acz�^�x�1|Ɛ���1IKK�5k�?�еk��zH&��d2"�����{�Wt:]AAA]5M\\�x&�q���D���w� v��y{{߹s���Y"�:t��������[�4���������oܸQ��͝;wӦM�0��d>�hL ++�?�sssgc����²�2"����?~��9��ʕ+999]�tqwwOMM�u떟�_˖-�����O/99����7�u��͞={˖-�3y�2�4&r���������N�s玭�m�� ++ŭ[��(''�}�����:����<y�x�''������D1������888��j" ++ �x>���%''���'�����k�Μ9��/��us �|�И���%$$�q�V�o���ݻ'.��q\LL����Ç���ήo߾�q���WPP���kii������TVV���R^^�w��'g2#�Ϟ=۽{�Z�������>#�^�|��/���]�v��?��?��IƜ�=� ���X999K�.���/k��Q^^>~��͛77k���� ��loo������^�zI�R�J��o�u�СM�6Dt�ܹ��<�|���z=�0fffR�T�V�jժcǎ�����^ ��kZ��I:����I�-z��x��իW�2***�,Y��K/�C�3`Y�}������������ѦM����������9;;�8q�����̌a�e��ӟ���`����S'�V{O8����I�&�ڵk���aaa���nnn���]�v�������)))~~~���q=z�HHH8v�D"�ӧ�!ƹ�����]�v���G��T����7n�m�688/���F���a��ºv���?DEE) ++[[[__�M�65k�,%%eٲe+W�|4�i4���jq[�T�������t:�at:ݕ+W�6m*���x�bNN������kEE� �t������ eee����~^��� �����)))111+W������,>>���*000!!A&�9::6o����>???//�����˫y��iii^^^M�49s��ݻw���z��%v%WTTdffv�رF�2< ++���d>���_��<�g�7d>�}� ��a���a��.�<���H$Z���KP0�����$@"�ɐ��4`�#@C��ЀXXX��j�FS�x&R���¢�K���!�������r�>h��R�\.LjI����!R*�*�J���'�a$�L&C@Ä����`�0������!�����>d>����Ӈ����`�������L2�����C����0}�|�����������!�����>d>����Ӈ����`�������L2�����C����0}�|�����������!�����>d>����Ӈ�/�K¾4>�P\%h��]��4�,??��Ka����P�u�a�e�R������Y}��!��g���Sz���� � z�^�T*�J�\neeU�%�K�|�b�T ��c���K�R���)A�˾4���DUU���]}��� ���%�"�<�FS�E��K�|�b)�B��'��|}�.!����t� ��&������!�����>d>����Ӈ�P�X��4:� 0Sߥ�����μݙ��/;r��Y}��(�-[������5\�JY;� o�uv��gzhC&7RRR����}����z�������8�\�z��ѣ�gϖH$D�{�n�=zN����Ν��xUee��ÇCCC���������`�М����???�Ri�_"�XZZ>�/����>�ѣGϞ=k=!>>���`̘1�^(�gvv�D"iڴ����ٳ�^�x���$88��*�R������-�JkL�����8�ξ�<���\�-L�˼֖9p�f��b�͓���ߧK�+�}�k��x832)]�uj\�7I��,/e��ヸ����L�c��=x����q�P.�*�Hy��.��#��d��\XXx��匌������lWWW''��G�0`ٲe�'O 5�|��ͼ�<1��<����3g�M�PDFF�1bԨQD�R��n�:p�@33��[�v��]�|III/^�p�BFF���oqq�5k��3|��9s�ۉ��eeeC�y�o���-[.�˟�b�^RRґ#Grss���j�m�����yA���ӧO�D"�ɾ��cǎ�'���{�������=�n�:GGG"JOO�8.000+++33S�|�������O��8n�̙���W�^5~���/G�^�bŊ>��몠���o�Y�p!Z1��Y�[R����f�`���������K���g���'��]Ykfs����2Z<DBD�:�酤BK'n�i������\�e~�/�3ف7����Y�ck��{���+���:�����b�'���l3����Q�&���=��I��UuPu�ʕ+6l���+--�7oްa��j5��ج\�ry�[�����j��.]�رcII�L&+...((���),,$"��V�Z5}���-[6mڴ��������F���B77733�v��ݻw���o�ԩgϞ ��O�"8p�����6��v�>}:�t����C�YXX�92$$D���?<x���y�رݺu�8�Y�f������Z}�h�nݺ�jժ�����믫W�^�t������+����m��o�ԩD4o���Y�f���ѨQ�n߾�z��E��T���r��n߾]ZZZUUu��m;;;�L&��^~��_~��~pvv���qc�N��H�R 4�����ϫ�j���u��ݻw����M��9r$>>���h���#G��J�D�v��#G�.����]]]�]��������\��Q@�xV����r�~CÐaI/)G���U���<���'K)���F��kN�D4���=���v�nW ++5�.X��T�������65��YA�ı�S*�g>ODz��(�P�.���E����z���0̻�����q��E4����ĉ���|||���'O�,^��w�͘1����͛'�9|�0yzz~��G���aaa�!C[�E�\]]���ӵkW"���zl����t:�������?��� +++#""������<x���y���t�����+Wv��i������ ��du[]O���ۋ- ++ }��gϞ�aÆ��{Ol1%������ǯX����+11q���cƌY�f����F�Q�վ��DIJ����ccc����k�����ƩS�V�\ٻw�!C��i�p�Z ��w�^�EVt���ݻw>FEE����;����H�aƎKD ++�bĈ���Ospp�8nԨQ��ы/��Jh��������N�p���b� ���^GD�0�����)ks����܂df������o�ҩ���'s����7��ؤ�#�c���E͝������D$�{k���uD�b�Q� >6��N�_/�c{��۳}�磼�\�R�Z�...���'"ss�<;;�{K$�VKD������D�}��������GDDѕ+W�-[f��8�Ol9rdtt���uHH����===�(""�_~OޱcGXXXrrr�>}w>|��q�����P�e�(==���b��߿������o߾ &�!��ڵk�������斖�ֽ{��^����.]�488����&"GG�5kք��/]�t��NNNDIJlPPPbb�������CBB���ϟ:t�!�ZXX���C�ݶm�q��NLLLff� �(++ː·>`��"�={������������j����_������#G������O?�����(88�}���w + +-:w�|��oo"2'N������6n�heeED���<����ODTZZ*�����bbb�Νk�W`F�V��� 3f�S��5�'++k���}�����rww���/mmm��___��D�W�.++��~&M[nn�ܹs daa�m۶V�ZU������"��ˋ��...&"�D2s���?�|ѢE͚5����p��;�C8��� 'A]RəA>������ǻ�y7,'YK��\��P�� .o��\U�i����T�)=�!�R��i�(�B��.�xy~��ߤG9)��Q��s�l�\��x����C�J��p_8��ٳ�������>rttl߾=YXX�^����[�v��ɓ:BD�6mZ�v��r������.]"���Ǜ�ܩS��'O�L&[�x������Ǐ�T������4"Z�b]�r����+V�ptt�1c���ǯ���q����Z�����7gg�N�:�v�R�����dffΚ5�U�VK�.�8n�ʕAAA;v����\����ҥK� �1bĈ7n\�l��������#""bڴi2��p���AN���炱rp�g����]$��j&6�Yznl��R�����I�Ǟ��j?'o���43(�c��M�T�$=-GG��r����I�����Î;�5kf�:cƌ�S�QFF�ĉ ++Z�fʹi�������!d>�g�&gV�&��Sw��Z82�vL�Bj�X˘�e2V�ld�.r�C?}Z���յq`f����'��y����F�)Jl���k��$t����D�r,C_�~���n�TB�� D�`ID��@n�9�S$l��' ++Dt�H��d�l��e n�{���#n���(""°�s��W�ر�e˖����G�V+&���R�ݩvvv����~�iӦM�8qΜ9={�=z����qk�����III���wv��Q�����yyy<ϗ����؈'�n�z�ƍz���8//��W��o櫮�o�7�|2~���� ++q�����e�,X0eʔE�������8;;�ܹ3$$�ĉ˗//**""�����V�5�� ++c�E��w�NJJ����7o����bffVc�XcYYY^^^bw-EGG�d���PC�3T,����,,,ܻw�M�ڴi��[o���r������͛�|��|�OO��.UBH[f�9�ZM/�`2B�f̵����,C�_���IOD��혷�����IB�CDr]�+���u�D��)��_/�������<���Ja��!���c�<eW��o�]�4����qcw��RD�ل��=�zzӦM�6m���'N|饗�(""���{Ĉ��ɭZ�rvv����y^�P�R�|������?���ٳg7i�D��Z[[�֭[�i���NNN���DTPP v���;;;;88���ݽ{��ٹ���PG�V��|UUUQQ�!C<8...,,�G�ݺucY688866���[�;v����� ++;;;q�ٿW���u�Vbb�1c���s�ĉG�r��!C���koo?e�q����(<<������S���d���<����w�y��/^\UU�P(��͍��YXX��ۻ��egg�N���������h�ZmiiYXXجY3q�͛7�o߾u�VC�3&3g�G������斐�0��;v���Q�6m�[W��x!�<=)CD*�f,��g �\"�vg��>hð�2U�Ǵ���Է=KD���Ez�K�^� ++% �Jk-%"bj-gv��g�&��,�s����֖Q��{*��������[4���^�J�~�I��̑��]%��dk�5�v>cZ�6''����iӦ������˖-۰a���3) ++ì�3f���;--mӦMK�,�h4b;� .\8|�p�Ri�7c�qcѢED$����%�3g�|��wgϞ��̬Q������Svvv�ӧOk��DGG���w���}ʔ)�F�rvv�p႘>ϝ;��+�1:t�u�V�e�TMD'N�4i��Z-Z����,>>���W�^mnn�`��9s�yzz����������'N�ؼy�x���ND�N�5j�̙3KJJ�A~���ԩS g���M�2���B����6l�0y�dOOO��cIII.\x���ŏ�ƍ7�7o~������6�����+++����L 2�ӳ2#"*SӅ>���ƌrK��.L�挍�9a�B��9�o�&y?�qIs���V����r��̀�� ++-��a�����d1�M����|(��̅�LD�S$��N�#����)r�"r�f�)KfRib૮���ξ~��ݻw�1y#G�l]LL̖-[BBB����3���{&N���;�9sF���������:>>����qqq�W��h4����_�~���W_}U*�fff�X����M������p����J����-//_�jՖ-[ڴiӻw��?���/�X�j���SdddYY���Mbb����ʼnJ�Rl\�_,ˊS�ŏ:����B�e�I�&b/��'V�Ze|�-[č֭[{zzfddt���p�7�x���G��r�ʎ;���믿5jԾ}�f̘!.�BD��|��x����\la�x�bJJJJJ��cǎ]�|y߾}�(;;{ժU~����q���.~"�������E�������W!���e�W3�r�`���]�KyB���w��o�"u�a6���VF�o���:90C��%1��A��a� ��7%nv�C���Vf��Ѵ�D�����ld4�G����~܆8=�VV�d'%��^rcR� ++J=QGg���D�Ɩa*���� �[���_mժ�F�y��w�bkk{�ڵ˗/+�-[��</N�x������ӳ��mll]�:&&��SAX�v�ԩS���9s��߿��%v_v��yÆ VVV,˖�����( ++�V+�0c�}��b��+gbb�8e�� ++��2�)�DdX�P��l�dX�p����w������3�|D��o� �Ю]��;w���˗W�Z�o߾�}�J�R��1b���u����mmmoID^^^�}��xBAAAxx���~*�9??�ҥ�����2���3#�A�T��ׯ��|�75^�������Z�3�**�R��~N�o�R��O̡=�>=�`�gjb��g g�"�$+sJ���Z-�J��)��\!���4<-��IY��Ծ���鈨\#Q�&LYu--sN2�ܛۓ��|�@D�혔{�\��b��J-���f�nD�Ҏtz��nCl�0a)S\\\�}�][[[Aĵ�&M�dkk#NέU�>}����o � ++����Z�Z�u+��ƁC�0�������#��e� ���F�٪U+1eJ�Rq�f"rww���ٱcGhh�Z�>t�8}���J��k����Ν3��s��ϯΫ�)�i���u�h߮������j������ 77�M�6��B�T*����.]*6k۶�̙3 �|����~�cǎeffΝ;W|yxx��5���kD���͚5��������ᖖ����D���r�ر���1cƸ������vvvb��y����-[�|��h�����^[g&��~`Z�p��m\VQ-�� H �d�R�1Z�}��,��D$x97�uanݫ�V�T4c��pfv%�==�w�����=�����R&=��$N/���m�\-��`9�_�-�?�T��;w�߿���755�_�~YYY͛7���+))18�=qI�K�. :�����/^ܡC�5k����s�ܹ,� ++�����Ν���srrlll�q"�NGDr��0������RRR���$����ݻw/_����r���bb@@@TTԡC�:w�i�&�mO�՞;w��7�|n�V��J�8W�Xzz�� �u�֣Gq9����FEE�3�{��z���ڶm+���ܹ�V�=<<��È�iiiinnn\�m۶-..�s玻�{�E�ꫯ + +-6lذr�������;f��P(֭[�T*����juAA�VVV���j���Ύ���ˋ���H��j�ڼ�<�T���%::z� ���[�t���/^,��������I$_�.((���x��7Y�=v�X�v킃�u:�X!99�ܹs������C#����j�RJ�������� ;�Ӌ���z1��F�n> +-R�l��%�e)G�Ui��f�<��?���,I�x��{�?��(q��[5�0D�ム2���x�K��0Au999�f������Ritt��ZTT�r��/���T944��͍����===M�v�����0a�B�Klmm���+���m0p����={������.qw��uq��nݺ5d�ӫ����{�=��BCC���L�����֭[]������]�vm��O?�8q"�U�J�҅v��i�ܹ~�a۶m�M����3gέ[�ڶm{�����`�Lf�I���3gά��q���@N�����E>��<]���j|���^lX���zy��<E����2ãd�����1�ZY��}�Nϧ��k�S����<a�9^SF�R�WTmF��j{��%�N�����8��-�c0W��F�0,�)�ʙ3g���HquϞ=����ƍ#"��Ȳ��Ieee��ͻq�F�Νž�^/�����˗��fϞݥK���ӪU�˗/����3fĈ�gϖ��eeecǎ�R�I��*~����ӧ�k�������ۦ�Q���SQQрv��٫W�_~�E,?q��իW����~���={VL�z�~��ݫW���C���u�BBDd0 +-�oC^�<�����y��ܙ�b���^I3Tpɱ�P+�ߙ���6�q�*2�vU3��+�����,aA/�e�َQ)Hϓ_��?��Ӌ�JJD�7�ӱ��ܞ����]�� ����Odee5x�`q9**���Ѵ������8x�����9s�[�����m�6"���#�E�Ѹqも��M�FD:�N�I���cǎ---}���g̘!��2x��fΜ���ТE�'N\�x1$$D"��?�l������ZAu=z�شiӫ��z�ĉ��r���ѣ� �=Z\�ر�믿~�ԩ{��:�������<x�S��H�-��-Zڭ[7[[[�bht���.)eDDe<}�d���w`?�5&e�<"zՕQ*�\�c�IJ��'ӄFb�iU�x +-�����$-.9�;�*��Z;1�2!�����c�k9Qgfh�������d˴we� �J�DDzm������'�B�w�^TT�͛7[�j���gϞ����˗����} O�R�V�Z���ߵkח^zɔ�T*�믿.�s""�Z}�ƍ�ݻW�BD�� ���s�N"*((^�d�x��������;wW1��Ӑ�dC�%�Q�F� +-�����Yh"V������/���t3�����ӧ�9�S�r�%1���螎�� +-�<X�5&� +-�|�V6��[�����u.��p`������UVM����t-�(嘜B��#r��θo�%�s��'�Ci-c����<*�}l�I �9�HD6 +-�����б�4 +-�\�r�Ν�W��9s������pqqaY633s�ʕ?���ѣGM�Z��gϞ�p����-[���ݻw�7o��|���FSe�%�ȑ#�FcdddPP�xs\��+D��w����|��z�����ƍb�������]V�gݻw�`����h4<ϋ������߯j_�v����w���7nРA�2˲C��-U��S�?�$�KJ9CDE%dzp� +-�%K�x��aG�x�/���g����oW���|X;+�*�����������Вy�3��߫#�hUo+��8����F�x7�O�qDt_#|z�HD6$�e��,��;��ӝ�}�g���������B^^�ĉ�ޣG�{��u��u������N�S(;v�www�y�rT2+$$$77���8//�cǎf�������T�U�����%K�����b&N�XVV��W_�S�Ws�f8::���k�~�/�%K�DDDT.9p��i999Y� ����ʢ�����+��Œ���(����FFF��T��s9 ꒻=��(KKDt��y����s���JJ����.���al-��獇+ʻ�32 c�����߳�r�fL�]a�Uc�V=,��ed)#1'�IX��)���z��{EB�f��ɴsa�~gH.2_����}��8�dFF�\.C��`طo�N�{�7|}}�h�֭~~~�os�N�R}��'D���ܧOS��|A����Ν�p�Bwww�{��Ș<yr����/Q�L&��JJJ�g������z�FCDJ���~/���ׯ[�N\^�f ��/6m5E"�{���{M�7o��������` +-I8�Ј 'A]j�Ȧ��ѕ�4�J�݆=���!���O��=W�'oW�9����o�����Z;1w��`r<Y8�E����P˲bH�,##��>;{��y�֭[�h�"ww��ׯw��E�IgΜ��ϧJV*�j�.\X�`��������+����ٳgϜ9300�T��ۻ���+��R����ӧ� �(��*�h�\n0�m��BCC۵k��G�%8�и 'A�q���.��_��#9�ǟR"�2�����;W�����iƑ/q�ҍYڪ�Rp�ە���Җ��oX+�)U��� �`<Դ�oEI\�������_+������Tn$)#���������F�0Lqq����ɓ'�{�9r�e˖���k֬�7o^||��~(�����tY�W�^b�Cjj�[�,,,���J���7egg������#!!!**�������*))Q*�<ϗ������_�>//��߿G���S�F����M�YYYW�^5]<�СC�gn@u�O��v4IJJ2�����R�ȑ#M�cƌ1u%''���[\�۷�)SL�p���AN�:�Ǎe:|�������}R +-�Y)m�`�3Io��C9;+�����,3{�0��ۣ������=�I��o~�����,���_��Cp��Ç�w�ND +-��믿���}������,Xзo߱cNJ�I...-[��r�)�ʭ[����f͚mٲE|�m�n�.\hii9bĈ������&%%edd<|����R�\.���pvv���OAL�^�8�����_�O#11133�r����˗/W.�������ٺ����P�(�*p���a�W+� � ݄�z6�s�$�f�<V_%#)G�t�$K SX&ܭ���*�c��E1��͂�j,C���@y:��'�?�I)f�4;;��[aFZZ�q*���58"2���NNN�ü�,A��[���������������S��������U9q<�ggg;::V�$�h��������Ԉ=�9 ��s����4��5@Nj��e�����I�����!'���������`r����y�I������EŲ��m +-p��Θ���9U�)x�!'5bs^�XIѥ���aY��m��1;��@��'o�@Z�x.�,�P(�j��wШa>n�����П���`r����y�I�����!'������u7�Zl�����IEND�B`� +\ No newline at end of file ++ ++��{���o��\.?y�dFFF@@���~*��[�n9::6o���B�xJf,��bO����nf��`�3s�s�ئ}ݏ=s�W>��qk9�l�Їa���IDATE��DM�5��p�c�Z���O�ג�!YODC�Ό�'+��S0��!N�G��������j>�c��6�ք�� 3�<��-�aT*Uuu��Y��z�ƍ���'L�����ڵ�����j�\�m�6�*��(!!��o��y>//��?$���(�Y�f���<xp����[=�m�I�&��qqq}���طKD������7n\XXX�&M���gΜY�mo-[�\�dI�G������7����o����Y�t��������Qbbbbbb��_y�+V�۷n���o�m������?~���5� ++ ++2^d���n��W߮حlee5v�ؓ'O��M�Z%k��`�Сb�7v��鰰�G�^@�|�O���ʔ��KBR�����y�Hkm:� Z�<�y��B�Jx����F�vi�B^���/�����x���B�e���-ȹ�1Uj��S�D�ݗ�1���01�ji��jtt�FC��%"�e�l�r�ҥN�:����n�Z�\�b�_|���^VV^��S�NC��y�s�����&L���a�y��f͚6mZuu��V�D"�H$R��0�B�ҭ[7��Scb����9rdBB�HM�]�v�c�Z�n]���jg;88̜9ӰH�������,--�_�ѪU�-[����!!!P�TUUU:��eY�Dbfff�ҕJ�aaaR��믿~���� 4y��#F���� ++�������g� ��`�nmR��d<�ٙ����ߛ�٘QE�=Vʒ� *�ׂ�^*ܪ��P�&��%���V�\3�����D�V�+�= ��\�ҡCC�yFnnn&\ϙ���[��練=�Z����6L�~ ++O����!����n3���|�δ3_���}������������!���E��2I��Qu5���@����_�1���x���F ++�^,]ܑ�����-�`b����2�{"�����qo~0 �|�b�qef��6��#��?���x{�d>x��c;�1����;BQ��)� b�eY�Tjee���k2����>������>d>����Ӈ����`�������L2�����C����0}�|�����������!�����>d>����Ӈ����`�������L2�����C����0}�|�����������!�����>d>�������(��O�I�����IEND�B`� +\ No newline at end of file +diff --git a/data/ukui-system-monitor/zh_CN/index.md b/data/ukui-system-monitor/zh_CN/index.md +index 77a1c67..83dcdf8 100644 +--- a/data/ukui-system-monitor/zh_CN/index.md ++++ b/data/ukui-system-monitor/zh_CN/index.md +@@ -14,7 +14,7 @@ + +  + +-- 用户可以选择进程的启动用户以及进程类别对进程进行切换,当前用户或是全部用户,亦或是应用程序的进程。 ++- 用户可以选择进程的启动用户以及进程类别对进程进行切换,当前用户或是全部用户,亦或是应用程序的进程,也可查看对应进程总数。 + + <br> + +diff --git a/src/controls/kchartview.cpp b/src/controls/kchartview.cpp +index 99e3d42..b7eafa9 100644 +--- a/src/controls/kchartview.cpp ++++ b/src/controls/kchartview.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "kchartview.h" + #include "../macro.h" + +diff --git a/src/controls/klabel.cpp b/src/controls/klabel.cpp +index af356c8..11b3565 100644 +--- a/src/controls/klabel.cpp ++++ b/src/controls/klabel.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "klabel.h" + + #include "../util.h" +diff --git a/src/dialog/customservicenamedlg.cpp b/src/dialog/customservicenamedlg.cpp +index b8016f0..a31f819 100644 +--- a/src/dialog/customservicenamedlg.cpp ++++ b/src/dialog/customservicenamedlg.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "customservicenamedlg.h" + + #include <QDebug> +diff --git a/src/dialog/onclosedialog.cpp b/src/dialog/onclosedialog.cpp +new file mode 100644 +index 0000000..19012ba +--- /dev/null ++++ b/src/dialog/onclosedialog.cpp +@@ -0,0 +1,104 @@ ++#include "onclosedialog.h" ++#include <QApplication> ++#include <kysdk/applications/klabel.h> ++ ++#include "macro.h" ++ ++#define ICON_EDIT_SIZE 16,16 ++ ++OnCloseDialog::OnCloseDialog(QWidget *parent) : KDialog(parent) ++{ ++ setWindowIcon(QIcon::fromTheme("ukui-system-monitor")); ++ setWindowTitle(tr("System Monitor")); ++ ++ const QByteArray ifid(MENU_SCHEMA); ++ if(QGSettings::isSchemaInstalled(ifid)) { ++ m_pSystemMonitorGSetting = new QGSettings(ifid); ++ } ++ ++ initUI(); ++ initStatus(); ++ setConnect(); ++} ++ ++OnCloseDialog::~OnCloseDialog() ++{ ++ ++} ++ ++void OnCloseDialog::initUI() ++{ ++ setFixedSize(376, 288); ++ KLabel *exitSettingTitleLabel = new KLabel(); ++ exitSettingTitleLabel->setLabelType(KLabelType::NormalType); ++ const auto radio = qApp->devicePixelRatio(); ++ exitSettingTitleLabel->setPixmap(QIcon::fromTheme("dialog-warning").pixmap(ICON_EDIT_SIZE*radio)); ++ exitSettingTitleLabel->setText(tr("When clicking the close button")); ++ QFont ft = exitSettingTitleLabel->font(); ++ ft.setBold(true); ++ exitSettingTitleLabel->setFont(ft); ++ ++ m_pMinimizeBtn = new QRadioButton(tr("Minimize to tray")); ++ m_pExitBtn = new QRadioButton(tr("Exit Application")); ++ m_pRadioBtnGroup = new QButtonGroup(); ++ m_pRadioBtnGroup->addButton(m_pMinimizeBtn, 0); ++ m_pRadioBtnGroup->addButton(m_pExitBtn, 1); ++ ++ m_pRememberCheckBox = new QCheckBox(tr("No more inquiries")); ++ ++ m_pCancelBtn = new KPushButton(); ++ m_pCancelBtn->setText(tr("Cancel")); ++ m_pConfirmBtn = new KPushButton(); ++ m_pConfirmBtn->setText(tr("Confirm")); ++ m_pConfirmBtn->setProperty("isImportant", true); ++ m_pConfirmBtn->setEnabled(true); ++ QHBoxLayout *bottomBtnsHorLayout= new QHBoxLayout; ++ bottomBtnsHorLayout->setContentsMargins(0, 0, 0, 0); ++ bottomBtnsHorLayout->addStretch(); ++ bottomBtnsHorLayout->addWidget(m_pCancelBtn); ++ bottomBtnsHorLayout->addWidget(m_pConfirmBtn); ++ ++ m_pMainVerLayout = new QVBoxLayout; ++ m_pMainVerLayout->setContentsMargins(48, 8, 16, 16); ++ m_pMainVerLayout->addWidget(exitSettingTitleLabel); ++ m_pMainVerLayout->addWidget(m_pMinimizeBtn); ++ m_pMainVerLayout->addWidget(m_pExitBtn); ++ m_pMainVerLayout->addWidget(m_pRememberCheckBox); ++ m_pMainVerLayout->addSpacing(24); ++ m_pMainVerLayout->addLayout(bottomBtnsHorLayout); ++ ++ mainWidget()->setLayout(m_pMainVerLayout); ++} ++ ++void OnCloseDialog::initStatus() ++{ ++ bool directlyExit = m_pSystemMonitorGSetting->get(DIRECTLY_EXIT).toBool(); ++ m_pExitBtn->setChecked(directlyExit); ++ m_pMinimizeBtn->setChecked(!directlyExit); ++ m_pRememberCheckBox->setChecked(false); ++} ++ ++void OnCloseDialog::setConnect() ++{ ++ connect(m_pCancelBtn, &KPushButton::clicked, this, [=](){ ++ this->close(); ++ }); ++ ++ connect(m_pConfirmBtn, &KPushButton::clicked, this, [=](){ ++ int checkedBtnId = m_pRadioBtnGroup->checkedId(); ++ m_pSystemMonitorGSetting->set(DIRECTLY_EXIT, checkedBtnId == 1 ? true : false); ++ if (checkedBtnId == 1) { ++ Q_EMIT needSaveSetting(); ++ qApp->exit(); ++ } else { ++ Q_EMIT closeMainWindow(); ++ } ++ ++ bool inquiries = m_pRememberCheckBox->isChecked(); ++ m_pSystemMonitorGSetting->set(INQUIRIES, !inquiries); ++ ++ this->close(); ++ }); ++ ++} ++ +diff --git a/src/dialog/onclosedialog.h b/src/dialog/onclosedialog.h +new file mode 100644 +index 0000000..5ced86a +--- /dev/null ++++ b/src/dialog/onclosedialog.h +@@ -0,0 +1,40 @@ ++#ifndef ONCLOSEDIALOG_H ++#define ONCLOSEDIALOG_H ++ ++#include <QObject> ++#include <QRadioButton> ++#include <QButtonGroup> ++#include <QCheckBox> ++#include <kysdk/applications/kdialog.h> ++#include <kysdk/applications/kpushbutton.h> ++using namespace kdk; ++ ++class OnCloseDialog : public KDialog ++{ ++ Q_OBJECT ++public: ++ OnCloseDialog(QWidget *parent = nullptr); ++ ~OnCloseDialog(); ++ ++private: ++ void initUI(); ++ void initStatus(); ++ void setConnect(); ++ ++private: ++ QVBoxLayout *m_pMainVerLayout = nullptr; ++ ++ KPushButton *m_pCancelBtn = nullptr; ++ KPushButton *m_pConfirmBtn = nullptr; ++ QRadioButton *m_pExitBtn = nullptr; ++ QRadioButton *m_pMinimizeBtn = nullptr; ++ QButtonGroup *m_pRadioBtnGroup = nullptr; ++ QCheckBox *m_pRememberCheckBox = nullptr; ++ ++ QGSettings *m_pSystemMonitorGSetting = nullptr; ++signals: ++ void closeMainWindow(); ++ void needSaveSetting(); ++}; ++ ++#endif // ONCLOSEDIALOG_H +diff --git a/src/dialog/settingdialog.cpp b/src/dialog/settingdialog.cpp +new file mode 100644 +index 0000000..a0dd1d1 +--- /dev/null ++++ b/src/dialog/settingdialog.cpp +@@ -0,0 +1,120 @@ ++#include "settingdialog.h" ++ ++#include <QFrame> ++#include <QPainter> ++#include <QVariant> ++#include <QApplication> ++ ++#include <kysdk/applications/klabel.h> ++ ++#include "macro.h" ++ ++SettingDialog::SettingDialog(QWidget *parent) : KDialog(parent) ++{ ++ setWindowIcon(QIcon::fromTheme("ukui-system-monitor")); ++ setWindowTitle(tr("System Monitor")); ++ ++ const QByteArray ifid(MENU_SCHEMA); ++ if(QGSettings::isSchemaInstalled(ifid)) { ++ m_pSystemMonitorGSetting = new QGSettings(ifid); ++ } ++ ++ initUI(); ++ initStatus(); ++ setConnect(); ++} ++ ++SettingDialog::~SettingDialog() ++{ ++ ++} ++ ++void SettingDialog::initUI() ++{ ++ setFixedSize(452, 243); ++ KLabel *exitSettingTitleLabel = new KLabel(); ++ exitSettingTitleLabel->setLabelType(KLabelType::NormalType); ++ exitSettingTitleLabel->setText(tr("Exit settings")); ++ QFont ft = exitSettingTitleLabel->font(); ++ ft.setBold(true); ++ exitSettingTitleLabel->setFont(ft); ++ ++ m_pMinimizeBtn = new QRadioButton(tr("Minimize to tray")); ++ m_pExitBtn = new QRadioButton(tr("Exit Application")); ++ m_pRadioBtnGroup = new QButtonGroup(); ++ m_pRadioBtnGroup->addButton(m_pMinimizeBtn, 0); ++ m_pRadioBtnGroup->addButton(m_pExitBtn, 1); ++ m_pExitSettingFrame = new SettingFrame(); ++ QVBoxLayout *VLayout = new QVBoxLayout; ++ VLayout->setContentsMargins(16, 0, 0, 0); ++ VLayout->addWidget(m_pMinimizeBtn); ++ VLayout->addWidget(m_pExitBtn); ++ m_pExitSettingFrame->setLayout(VLayout); ++ ++ m_pCancelBtn = new KPushButton(); ++ m_pCancelBtn->setText(tr("Cancel")); ++ m_pConfirmBtn = new KPushButton(); ++ m_pConfirmBtn->setText(tr("Confirm")); ++ m_pConfirmBtn->setProperty("isImportant", true); ++ m_pConfirmBtn->setEnabled(true); ++ QHBoxLayout *bottomBtnsHorLayout= new QHBoxLayout; ++ bottomBtnsHorLayout->setContentsMargins(0, 0, 0, 0); ++ bottomBtnsHorLayout->addStretch(); ++ bottomBtnsHorLayout->addWidget(m_pCancelBtn); ++ bottomBtnsHorLayout->addWidget(m_pConfirmBtn); ++ ++ m_pMainVerLayout = new QVBoxLayout; ++ m_pMainVerLayout->setContentsMargins(24, 10, 24, 24); ++ m_pMainVerLayout->addWidget(exitSettingTitleLabel); ++ m_pMainVerLayout->addWidget(m_pExitSettingFrame); ++ m_pMainVerLayout->addSpacing(24); ++ m_pMainVerLayout->addLayout(bottomBtnsHorLayout); ++ ++ mainWidget()->setLayout(m_pMainVerLayout); ++ update(); ++} ++ ++void SettingDialog::initStatus() ++{ ++ bool directlyExit = m_pSystemMonitorGSetting->get(DIRECTLY_EXIT).toBool(); ++ m_pExitBtn->setChecked(directlyExit); ++ m_pMinimizeBtn->setChecked(!directlyExit); ++} ++ ++void SettingDialog::setConnect() ++{ ++ connect(m_pCancelBtn, &KPushButton::clicked, this, [=](){ ++ this->close(); ++ }); ++ ++ connect(m_pConfirmBtn, &KPushButton::clicked, this, [=](){ ++ int checkedBtnId = m_pRadioBtnGroup->checkedId(); ++ m_pSystemMonitorGSetting->set(DIRECTLY_EXIT, checkedBtnId == 1 ? true : false); ++ ++ this->close(); ++ }); ++ ++} ++ ++SettingFrame::SettingFrame(QWidget *parent) : QFrame(parent) ++{ ++} ++ ++SettingFrame::~SettingFrame() ++{ ++} ++ ++void SettingFrame::paintEvent(QPaintEvent *event) ++{ ++ QPalette palette = qApp->palette(); ++ QColor color = palette.color(QPalette::Active, QPalette::Window); ++ ++ QPainter painter(this); ++ painter.save(); ++ painter.setRenderHint(QPainter::Antialiasing, true); ++ painter.setBrush(color); ++ painter.setPen(Qt::transparent); ++ QRect rect = this->rect(); ++ painter.drawRoundedRect(rect.x() + 1, rect.y() + 1, rect.width() - 2, rect.height() - 2, 6, 6); ++ QFrame::paintEvent(event); ++} +diff --git a/src/dialog/settingdialog.h b/src/dialog/settingdialog.h +new file mode 100644 +index 0000000..56413a3 +--- /dev/null ++++ b/src/dialog/settingdialog.h +@@ -0,0 +1,48 @@ ++#ifndef SETTINGDIALOG_H ++#define SETTINGDIALOG_H ++ ++#include <QObject> ++#include <QRadioButton> ++#include <QVBoxLayout> ++#include <QButtonGroup> ++#include <kysdk/applications/kpushbutton.h> ++#include <kdialog.h> ++using namespace kdk; ++ ++ ++class SettingFrame : public QFrame ++{ ++public: ++ SettingFrame(QWidget *parent = nullptr); ++ ~SettingFrame(); ++ ++protected: ++ void paintEvent(QPaintEvent *event); ++}; ++ ++class SettingDialog : public KDialog ++{ ++ Q_OBJECT ++public: ++ SettingDialog(QWidget *parent = nullptr); ++ ~SettingDialog(); ++ ++private: ++ void initUI(); ++ void initStatus(); ++ void setConnect(); ++ ++private: ++ QVBoxLayout *m_pMainVerLayout = nullptr; ++ ++ KPushButton *m_pCancelBtn = nullptr; ++ KPushButton *m_pConfirmBtn = nullptr; ++ QRadioButton *m_pExitBtn = nullptr; ++ QRadioButton *m_pMinimizeBtn = nullptr; ++ QButtonGroup *m_pRadioBtnGroup = nullptr; ++ SettingFrame *m_pExitSettingFrame = nullptr; ++ ++ QGSettings *m_pSystemMonitorGSetting = nullptr; ++}; ++ ++#endif // SETTINGDIALOG_H +diff --git a/src/dialog/uslider.cpp b/src/dialog/uslider.cpp +index 819ca66..982ccfe 100644 +--- a/src/dialog/uslider.cpp ++++ b/src/dialog/uslider.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "uslider.h" + #include <QDebug> + +diff --git a/src/filesystem/filesysteminfoitem.cpp b/src/filesystem/filesysteminfoitem.cpp +index 1ba03eb..fae15b3 100644 +--- a/src/filesystem/filesysteminfoitem.cpp ++++ b/src/filesystem/filesysteminfoitem.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "filesysteminfoitem.h" + #include "../macro.h" + +diff --git a/src/filesystem/filesystemwidget.cpp b/src/filesystem/filesystemwidget.cpp +index 5e53f46..f588516 100644 +--- a/src/filesystem/filesystemwidget.cpp ++++ b/src/filesystem/filesystemwidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "filesystemwidget.h" + #include "filesysteminfoitem.h" + +diff --git a/src/kleftwidget.cpp b/src/kleftwidget.cpp +index 02b3bc9..6080398 100644 +--- a/src/kleftwidget.cpp ++++ b/src/kleftwidget.cpp +@@ -355,6 +355,8 @@ void KLeftWidget::onResourceUpdate() + emit updateMemStatus(memUsed, memTotal); + emit updateSwapStatus(swapUsed, swapTotal); + ++ qDebug() << Q_FUNC_INFO << "memUsed = " << memUsed << ";memTotal = " << memTotal << ";swapUsed = " << swapUsed << ";swapTotal = " << swapTotal; ++ + //net work data get signal + getNetworkBytesData(m_totalRecvBytes, m_totalSentBytes, m_rateRecvBytes, m_rateSentBytes); + emit onUpdateNetStatus(m_totalSentBytes, m_rateSentBytes, m_totalRecvBytes, m_rateRecvBytes); +diff --git a/src/krightwidget.cpp b/src/krightwidget.cpp +index 70c1a4b..55b9ad2 100644 +--- a/src/krightwidget.cpp ++++ b/src/krightwidget.cpp +@@ -31,6 +31,9 @@ + #include <QDBusMessage> + #include "util.h" + ++#include "dialog/settingdialog.h" ++#include "dialog/onclosedialog.h" ++ + QString KRightWidget::searchText = ""; + + KRightWidget::KRightWidget(QWidget *parent) +@@ -39,6 +42,12 @@ KRightWidget::KRightWidget(QWidget *parent) + this->setAttribute(Qt::WA_TranslucentBackground); + this->installEventFilter(this); + initUI(); ++ ++ const QByteArray ifid(MENU_SCHEMA); ++ if(QGSettings::isSchemaInstalled(ifid)) { ++ m_pSystemMonitorGSetting = new QGSettings(ifid); ++ } ++ + initConnections(); + } + +@@ -72,7 +81,6 @@ void KRightWidget::initUI() + // 初始化控件 + m_mainMenu = new KMenuButton(); + m_mainMenu->themeAction()->setVisible(false); +- m_mainMenu->settingAction()->setVisible(false); + m_mainMenu->feedbackAction()->setVisible(true); + m_btnMin = new QToolButton(this); + m_btnMin->setToolTip(tr("Minimize")); +@@ -103,7 +111,16 @@ void KRightWidget::initUI() + k_aboutDialog->exec(); + }); + connect(m_mainMenu->assistAction(), &QAction::triggered, this, &KRightWidget::showUserGuide); +- connect(m_mainMenu->quitAction(), &QAction::triggered, this, [=]{ ++ ++ connect(m_mainMenu->settingAction(), &QAction::triggered, this, [=](){ ++ // setting dialog ++ SettingDialog *settingDialog = new SettingDialog(this); ++ ++ settingDialog->exec(); ++ }); ++ ++ connect(m_mainMenu->quitAction(),&QAction::triggered,this,[=]{ ++ Q_EMIT needSaveSetting(); + qApp->exit(); + }); + +diff --git a/src/krightwidget.h b/src/krightwidget.h +index 66565a9..7b7fbe1 100644 +--- a/src/krightwidget.h ++++ b/src/krightwidget.h +@@ -68,6 +68,7 @@ signals: + void minimizeWindow(); + void canelSearchEditFocus(); + void searchSignal(QString searchContent); ++ void needSaveSetting(); + + protected: + void paintEvent(QPaintEvent *) override; +@@ -95,6 +96,7 @@ private: + bool m_isSearching = false; + + QGSettings *m_styleSettings = nullptr; ++ QGSettings *m_pSystemMonitorGSetting = nullptr; + + public: + static QString searchText; +diff --git a/src/macro.h b/src/macro.h +index f2235bb..a51e6d9 100644 +--- a/src/macro.h ++++ b/src/macro.h +@@ -148,5 +148,7 @@ enum SIGTYPE + #define WHICH_MENU_KEY "whichMenu" + #define SUPPORT_SERVICE "support-service" + #define SUPPORT_SERVICE_KEY "supportService" ++#define DIRECTLY_EXIT "exit" ++#define INQUIRIES "inquiries" + + #endif +diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp +index 1bc1750..ac31720 100644 +--- a/src/mainwindow.cpp ++++ b/src/mainwindow.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "mainwindow.h" + #include "macro.h" + +@@ -12,6 +31,9 @@ + #include <QDebug> + #include "ukuistylehelper/ukuistylehelper.h" + #include <KWindowEffects> ++#include <QSessionManager> ++ ++#include "dialog/onclosedialog.h" + + MainWindow::MainWindow(QWidget *parent) + : QFrame(parent) +@@ -46,7 +68,23 @@ MainWindow::MainWindow(QWidget *parent) + + TrayIcon *m_trayIcon = new TrayIcon(m_leftWidget->getCpuHisWidget(), m_leftWidget->getMemHisWidget(), m_leftWidget->getNetHisWidget()); + connect(m_trayIcon, &TrayIcon::openMonitor, this, &MainWindow::handleMessage); ++ connect(m_trayIcon, &TrayIcon::needSaveSetting, this, &MainWindow::saveSettings); + #endif ++ ++ const QByteArray ifid(MENU_SCHEMA); ++ if(QGSettings::isSchemaInstalled(ifid)) { ++ m_pSystemMonitorGSetting = new QGSettings(ifid); ++ } ++ ++ QObject::connect(qApp, &QApplication::commitDataRequest, [=](QSessionManager &sessionManager){ ++ isShutDown = true; ++ qDebug() << "logout,shutdown,reboot"; ++ }); ++ ++ QObject::connect(qApp, &QApplication::saveStateRequest, [=](QSessionManager &sessionManager){ ++ isShutDown = false; ++ qDebug() << "cancel logout,shutdown,reboot"; ++ }); + } + + MainWindow::~MainWindow() +@@ -100,6 +138,7 @@ void MainWindow::initConnections() + connect(m_leftWidget, SIGNAL(switchPage(int)), this, SLOT(onSwitchPage(int))); + connect(m_rightWidget, SIGNAL(maximizeWindow()), this, SLOT(onMaximizeWindow())); + connect(m_rightWidget, SIGNAL(minimizeWindow()), this, SLOT(onMinimizeWindow())); ++ connect(m_rightWidget, &KRightWidget::needSaveSetting, this, &MainWindow::saveSettings); + if (m_procWidget) { + connect(m_rightWidget, &KRightWidget::searchSignal, m_procWidget, &ProcessWidget::searchSignal); + } +@@ -226,6 +265,7 @@ void MainWindow::handleMessage(const QString &msg) + this->showMinimized(); + } else { + QString platform = QGuiApplication::platformName(); ++ qDebug() << Q_FUNC_INFO << platform; + if(platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive)) { + if (!m_listWinIds.isEmpty()) { + WindowManager::activateWindow(m_listWinIds.back()); +@@ -292,6 +332,40 @@ bool MainWindow::dblOnEdge(QMouseEvent *event) + + bool MainWindow::eventFilter(QObject *watched, QEvent *event) + { ++ if (event->type() == QEvent::Close) { ++ ++ qDebug() << event->type(); ++ ++ // get configure ++ if (isShutDown) { ++ qApp->exit(); ++ } else { ++ bool inquiries = m_pSystemMonitorGSetting->get(INQUIRIES).toBool(); ++ if (inquiries) { ++ event->ignore(); ++ ++ // show dialog ++ OnCloseDialog *closeSettingDialog = new OnCloseDialog(this); ++ connect(closeSettingDialog, &OnCloseDialog::closeMainWindow, this, [=](){ ++ window()->close(); ++ event->accept(); ++ }); ++ connect(closeSettingDialog, &OnCloseDialog::needSaveSetting, this, &MainWindow::saveSettings); ++ ++ closeSettingDialog->exec(); ++ } else { ++ bool directlyExit = m_pSystemMonitorGSetting->get(DIRECTLY_EXIT).toBool(); ++ if (directlyExit) { ++ saveSettings(); ++ qApp->exit(); ++ } else { ++ window()->close(); ++ } ++ } ++ } ++ ++ } ++ + if (this == watched) { + + if (event->type() == QEvent::MouseButtonDblClick) { +@@ -346,16 +420,7 @@ void MainWindow::keyReleaseEvent(QKeyEvent *e) + + void MainWindow::closeEvent(QCloseEvent *event) + { +- m_lastWndSize = size(); +- m_bIsWndMax = isMaximized(); +- if (m_procWidget) { +- m_procWidget->onWndClose(); +- } +- if (m_svcWidget) { +- m_svcWidget->onWndClose(); +- } + saveSettings(); +- event->accept(); + } + + void MainWindow::mouseMoveEvent(QMouseEvent *event) +@@ -397,6 +462,15 @@ bool MainWindow::loadSettings() + + void MainWindow::saveSettings() + { ++ m_lastWndSize = size(); ++ m_bIsWndMax = isMaximized(); ++ if (m_procWidget) { ++ m_procWidget->onWndClose(); ++ } ++ if (m_svcWidget) { ++ m_svcWidget->onWndClose(); ++ } ++ + if (m_proSettings) { + m_proSettings->beginGroup("SystemMonitor"); + m_proSettings->setValue(MAINWINDOW_SIZE_W, m_lastWndSize.width()); +diff --git a/src/mainwindow.h b/src/mainwindow.h +index 7bc2a2a..4848305 100644 +--- a/src/mainwindow.h ++++ b/src/mainwindow.h +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #ifndef MAINWINDOW_H + #define MAINWINDOW_H + +@@ -44,6 +63,7 @@ public slots: + void onMaximizeWindow(); + void switchPage(int nIndex); + void tabletmodeDbusSlot(bool isTabletmode); ++ void saveSettings(); + + signals: + +@@ -65,7 +85,7 @@ private: + void initRightPanel(); + void getOsRelease(); + bool loadSettings(); +- void saveSettings(); ++ + bool dblOnEdge(QMouseEvent *event); + void moveCenter(); + +@@ -97,7 +117,11 @@ private: + DiskDetailsWidget *m_pDiskDetailsWidget = nullptr; + + QList<WindowId> m_listWinIds; ++ + int mFirstKey = 0; ++ ++ QGSettings *m_pSystemMonitorGSetting = nullptr; ++ bool isShutDown = false; + }; + + #endif // MAINWINDOW_H +diff --git a/src/process/process_list.cpp b/src/process/process_list.cpp +index 9cddae2..2ecef52 100644 +--- a/src/process/process_list.cpp ++++ b/src/process/process_list.cpp +@@ -1068,7 +1068,7 @@ void ProcessList::scanProcess() + bool bFilterActive = false; + bool bFilterApp = false; + bool bFilterUser = false; +- uid_t curUID = -1; ++ uid_t curUID = getuid(); + bool bQuickUpdate = false; + + // 过滤频繁计算cpu消耗占比数据不准确问题 +@@ -1089,7 +1089,6 @@ void ProcessList::scanProcess() + arg = 0; + } else if (m_strFilter == "user") { + which = GLIBTOP_KERN_PROC_ALL; +- curUID = getuid(); + bFilterUser = true; + } else if (m_strFilter == "applications") { + which = GLIBTOP_KERN_PROC_ALL; +@@ -1142,6 +1141,9 @@ void ProcessList::scanProcess() + } + } + ++ int allProcCount = 0; ++ int appProcCount = 0; ++ int userProcCount = 0; + for(int i = 0; i < validList.size(); ++i) + { + pid_t pidCur = validList[i]; +@@ -1276,6 +1278,19 @@ void ProcessList::scanProcess() + proc.setProcCpuDurationTime(formatDurationForDisplay(100 * proc.getProcCpuTime() / proc.getFrequency())); + proc.setProcStatus(formatProcessState(proc.getStatus())); + ++ if (proc.getStatus() != GLIBTOP_PROCESS_ZOMBIE) { ++ allProcCount++; ++ } ++ if (m_listGuiPids.contains(proc.pid()) ++ && proc.getProcName() != "peony-qt-desktop" ++ && proc.getProcName() != "ukui-panel" ++ && proc.getProcName() != "ukui-menu" ++ && proc.getProcName() != "ukui-tablet-desktop") { ++ appProcCount++; ++ } ++ if (proc.getStatus() != GLIBTOP_PROCESS_ZOMBIE && curUID == procstate.uid) { ++ userProcCount++; ++ } + + if (proc.getStatus() == GLIBTOP_PROCESS_ZOMBIE) { + if (m_set.contains(proc.pid())) { +@@ -1294,7 +1309,7 @@ void ProcessList::scanProcess() + appList.removeOne(proc.pid()); + removeProcess(proc.pid()); + } +- }else if (bFilterUser && curUID != procstate.uid) { ++ } else if (bFilterUser && curUID != procstate.uid) { + // 移除非当前用户进程 + if (m_set.contains(proc.pid())) { + removeProcess(proc.pid()); +@@ -1309,6 +1324,9 @@ void ProcessList::scanProcess() + } + } + ++ Q_EMIT procCountUpdated(appProcCount, userProcCount, allProcCount); ++ qDebug() << appProcCount << userProcCount << allProcCount << m_set.count(); ++ + // 合并应用程序子进程网络、处理器、磁盘、内存信息 + for (const pid_t &pid : appList) { + qreal mergeBps = 0; +@@ -1369,8 +1387,17 @@ Process ProcessList::getProcessById(pid_t pid) + + QList<pid_t> ProcessList::getPIDList() + { +- QList<pid_t> pidList; +- pidList = m_set.keys(); ++ QList<pid_t> pidList{}; ++ pidList.clear(); ++ int size = m_set.size(); ++ QMap<pid_t, Process>::key_iterator iterBegin = m_set.keyBegin(); ++ for (; iterBegin != m_set.keyEnd(); ++iterBegin) { ++ pid_t tmpKey = *iterBegin; ++ pidList.append(tmpKey); ++ if (size != m_set.size()) { ++ break; ++ } ++ } + return pidList; + } + +diff --git a/src/process/process_list.h b/src/process/process_list.h +index 2587978..2214188 100644 +--- a/src/process/process_list.h ++++ b/src/process/process_list.h +@@ -224,6 +224,7 @@ Q_SIGNALS: + void priorityPromoteResultReady(const int &ec); + void processControlResultReady(const int &ec); + void filterTypeChanged(FilterType filter); ++ void procCountUpdated(int appCount, int myCount, int AllCount); + + private: + void mergeSubProcNetIO(pid_t ppid, qreal &mergeBps); +diff --git a/src/process/processwidget.cpp b/src/process/processwidget.cpp +index 993dcef..771e3c5 100644 +--- a/src/process/processwidget.cpp ++++ b/src/process/processwidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "processwidget.h" + + #include <QPainterPath> +@@ -10,6 +29,9 @@ + #include "../macro.h" + #include "../util.h" + ++#include "../process/process_monitor.h" ++using namespace sysmonitor::process; ++ + ProcessWidget::ProcessWidget(QSettings *proSettings, QWidget *parent) + : QWidget(parent) + , m_proSettings(proSettings) +@@ -96,6 +118,17 @@ void ProcessWidget::initConnections() + connect(this,SIGNAL(changeProcessItemDialog(int)), m_procTabView, SLOT(onChangeProcessFilter(int))); + connect(processTabBar, SIGNAL(currentChanged(int)), this, SLOT(onSwitchProcType(int))); + connect(this, SIGNAL(searchSignal(QString)), m_procTabView, SLOT(onSearch(QString)), Qt::QueuedConnection); ++ ++ auto *monitor = ProcessMonitor::instance(); ++ //update process count from model's cache on process processupdated signal ++ connect(monitor->processList(), &ProcessList::procCountUpdated, this, &ProcessWidget::updateProcCount); ++} ++ ++void ProcessWidget::updateProcCount(int appCount, int myCount, int AllCount) ++{ ++ processTabBar->setTabText(0, tr("Applications(%1)").arg(appCount)); ++ processTabBar->setTabText(1, tr("My Processes(%1)").arg(myCount)); ++ processTabBar->setTabText(2, tr("All Process(%1)").arg(AllCount)); + } + + void ProcessWidget::initThemeMode() +diff --git a/src/process/processwidget.h b/src/process/processwidget.h +index cb9bc68..ee21b75 100644 +--- a/src/process/processwidget.h ++++ b/src/process/processwidget.h +@@ -28,6 +28,7 @@ public: + + public slots: + void onSwitchProcType(int nType); ++ void updateProcCount(int appCount, int myCount, int AllCount); + + signals: + void changeProcessItemDialog(int itemIndex); +diff --git a/src/process/processwndinfo.cpp b/src/process/processwndinfo.cpp +index 372813d..3491f07 100644 +--- a/src/process/processwndinfo.cpp ++++ b/src/process/processwndinfo.cpp +@@ -1,5 +1,26 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "processwndinfo.h" + ++#include <QDebug> ++ + #include "kysdk/applications/windowmanager/windowmanager.h" + using namespace kdk; + +@@ -24,6 +45,7 @@ void ProcessWndInfo::updateWindowInfos() + wndInfo.wndName = kdk::WindowManager::getWindowTitle(w); + wndInfo.wndIcon = kdk::WindowManager::getWindowIcon(w); + m_mapProcWndInfos[wndInfo.procId] = wndInfo; ++ qDebug() << Q_FUNC_INFO << wndInfo.procId << wndInfo.wndName << wndInfo.wndIcon; + } + } + } +diff --git a/src/service/dbuspropertiesinterface.cpp b/src/service/dbuspropertiesinterface.cpp +index 5facecb..af56f34 100644 +--- a/src/service/dbuspropertiesinterface.cpp ++++ b/src/service/dbuspropertiesinterface.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "dbuspropertiesinterface.h" + + DBusPropertiesInterface::DBusPropertiesInterface(const QString &service, +diff --git a/src/service/kerror.cpp b/src/service/kerror.cpp +index 1626c73..30df2e5 100644 +--- a/src/service/kerror.cpp ++++ b/src/service/kerror.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "kerror.h" + + #include <QString> +diff --git a/src/service/servicedataworker.cpp b/src/service/servicedataworker.cpp +index 4dd17bd..e9aba1c 100644 +--- a/src/service/servicedataworker.cpp ++++ b/src/service/servicedataworker.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "servicedataworker.h" + + #include "servicecommon.h" +diff --git a/src/service/servicefileinfo.cpp b/src/service/servicefileinfo.cpp +index 9906c77..7ed8bc1 100644 +--- a/src/service/servicefileinfo.cpp ++++ b/src/service/servicefileinfo.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "servicefileinfo.h" + + #include <QString> +diff --git a/src/service/serviceinfo.cpp b/src/service/serviceinfo.cpp +index 892eb2a..61e6849 100644 +--- a/src/service/serviceinfo.cpp ++++ b/src/service/serviceinfo.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "serviceinfo.h" + + #include <QString> +diff --git a/src/service/servicemanager.cpp b/src/service/servicemanager.cpp +index 6738af0..8d39179 100644 +--- a/src/service/servicemanager.cpp ++++ b/src/service/servicemanager.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "servicemanager.h" + + #include "servicecommon.h" +diff --git a/src/service/servicewidget.cpp b/src/service/servicewidget.cpp +index 84f23aa..76586c6 100644 +--- a/src/service/servicewidget.cpp ++++ b/src/service/servicewidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "servicewidget.h" + + #include <QPainterPath> +diff --git a/src/service/systemd1managerinterface.cpp b/src/service/systemd1managerinterface.cpp +index 978c3bb..6f99fcf 100644 +--- a/src/service/systemd1managerinterface.cpp ++++ b/src/service/systemd1managerinterface.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "systemd1managerinterface.h" + + Systemd1ManagerInterface::Systemd1ManagerInterface(const QString &service, +diff --git a/src/service/systemd1serviceinterface.cpp b/src/service/systemd1serviceinterface.cpp +index f45acb0..dad3039 100644 +--- a/src/service/systemd1serviceinterface.cpp ++++ b/src/service/systemd1serviceinterface.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "systemd1serviceinterface.h" + + #include <QVariant> +diff --git a/src/src.pro b/src/src.pro +index d2d7344..c84d5fc 100644 +--- a/src/src.pro ++++ b/src/src.pro +@@ -75,6 +75,8 @@ HEADERS += \ + controls/klabel.h \ + controls/kprogressbar.h \ + dialog/customservicenamedlg.h \ ++ dialog/onclosedialog.h \ ++ dialog/settingdialog.h \ + dialog/uslider.h \ + filesystem/datacdrom.h \ + filesystem/filesysteminfoitem.h \ +@@ -149,6 +151,8 @@ SOURCES += \ + controls/klabel.cpp \ + controls/kprogressbar.cpp \ + dialog/customservicenamedlg.cpp \ ++ dialog/onclosedialog.cpp \ ++ dialog/settingdialog.cpp \ + dialog/uslider.cpp \ + filesystem/datacdrom.cpp \ + filesystem/filesysteminfoitem.cpp \ +diff --git a/src/sysresource/basedetailviewwidget.cpp b/src/sysresource/basedetailviewwidget.cpp +index 14313e9..45918ff 100644 +--- a/src/sysresource/basedetailviewwidget.cpp ++++ b/src/sysresource/basedetailviewwidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "basedetailviewwidget.h" + + BaseDetailViewWidget::BaseDetailViewWidget(QWidget *parent) +diff --git a/src/sysresource/chartviewwidget.cpp b/src/sysresource/chartviewwidget.cpp +index 6c40f32..5f45152 100644 +--- a/src/sysresource/chartviewwidget.cpp ++++ b/src/sysresource/chartviewwidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "chartviewwidget.h" + #include <QLabel> + #include <QHBoxLayout> +diff --git a/src/sysresource/commoninfo.cpp b/src/sysresource/commoninfo.cpp +index 98eed5d..7372999 100644 +--- a/src/sysresource/commoninfo.cpp ++++ b/src/sysresource/commoninfo.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "commoninfo.h" + #include <QDebug> + +diff --git a/src/sysresource/cpudetailsmodel.cpp b/src/sysresource/cpudetailsmodel.cpp +index f6022bc..319b206 100644 +--- a/src/sysresource/cpudetailsmodel.cpp ++++ b/src/sysresource/cpudetailsmodel.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "cpudetailsmodel.h" + + CpuDetailsModel::CpuDetailsModel(QObject *parent) +diff --git a/src/sysresource/cpudetailswidget.cpp b/src/sysresource/cpudetailswidget.cpp +index 3c3adb5..2118eac 100644 +--- a/src/sysresource/cpudetailswidget.cpp ++++ b/src/sysresource/cpudetailswidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "cpudetailswidget.h" + + #include <libkycpu.h> +diff --git a/src/sysresource/cpuhistorywidget.cpp b/src/sysresource/cpuhistorywidget.cpp +index 0baf3ff..e45f615 100644 +--- a/src/sysresource/cpuhistorywidget.cpp ++++ b/src/sysresource/cpuhistorywidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "cpuhistorywidget.h" + #include "../macro.h" + +diff --git a/src/sysresource/detaillisttable.cpp b/src/sysresource/detaillisttable.cpp +index 9febcca..fa0558a 100644 +--- a/src/sysresource/detaillisttable.cpp ++++ b/src/sysresource/detaillisttable.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "detaillisttable.h" + #include <QPainter> + +diff --git a/src/sysresource/lightlabel.cpp b/src/sysresource/lightlabel.cpp +index 0793f81..75356cf 100644 +--- a/src/sysresource/lightlabel.cpp ++++ b/src/sysresource/lightlabel.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "lightlabel.h" + + LightLabel::LightLabel(QWidget *parent): +diff --git a/src/sysresource/memdetailsmodel.cpp b/src/sysresource/memdetailsmodel.cpp +index c3bd5fe..46c6ed3 100644 +--- a/src/sysresource/memdetailsmodel.cpp ++++ b/src/sysresource/memdetailsmodel.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "memdetailsmodel.h" + + MemDetailsModel::MemDetailsModel(QObject *parent) +diff --git a/src/sysresource/memdetailswidget.cpp b/src/sysresource/memdetailswidget.cpp +index 1c81c0c..0f93ea6 100644 +--- a/src/sysresource/memdetailswidget.cpp ++++ b/src/sysresource/memdetailswidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "memdetailswidget.h" + + MemDetailsWidget::MemDetailsWidget(QWidget *parent) : BaseDetailViewWidget(parent) +diff --git a/src/sysresource/memhistorywidget.cpp b/src/sysresource/memhistorywidget.cpp +index 6e3f372..2f029e0 100644 +--- a/src/sysresource/memhistorywidget.cpp ++++ b/src/sysresource/memhistorywidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "memhistorywidget.h" + #include "../macro.h" + #include "../util.h" +diff --git a/src/sysresource/netdetailsmodel.cpp b/src/sysresource/netdetailsmodel.cpp +index ae2b5fe..095dc42 100644 +--- a/src/sysresource/netdetailsmodel.cpp ++++ b/src/sysresource/netdetailsmodel.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "netdetailsmodel.h" + + NetInfoDetailItemDelegate::NetInfoDetailItemDelegate(QObject *parent): QStyledItemDelegate(parent) +diff --git a/src/sysresource/netdetailswidget.cpp b/src/sysresource/netdetailswidget.cpp +index f48d690..2978801 100644 +--- a/src/sysresource/netdetailswidget.cpp ++++ b/src/sysresource/netdetailswidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "netdetailswidget.h" + + NetDetailsWidget::NetDetailsWidget(QWidget *parent) : BaseDetailViewWidget(parent) +diff --git a/src/sysresource/nethistorywidget.cpp b/src/sysresource/nethistorywidget.cpp +index 79aa81a..2433d7d 100644 +--- a/src/sysresource/nethistorywidget.cpp ++++ b/src/sysresource/nethistorywidget.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "nethistorywidget.h" + #include "../macro.h" + #include "../util.h" +diff --git a/src/sysresource/netviewscrollarea.cpp b/src/sysresource/netviewscrollarea.cpp +index 64d5acc..ec7e6cd 100644 +--- a/src/sysresource/netviewscrollarea.cpp ++++ b/src/sysresource/netviewscrollarea.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "netviewscrollarea.h" + #include <QDebug> + +diff --git a/src/translation/ukui-system-monitor_bo_CN.ts b/src/translation/ukui-system-monitor_bo_CN.ts +index a6726d7..a348e4e 100644 +--- a/src/translation/ukui-system-monitor_bo_CN.ts ++++ b/src/translation/ukui-system-monitor_bo_CN.ts +@@ -300,23 +300,11 @@ + <location filename="../krightwidget.cpp" line="100"/> + <location filename="../krightwidget.cpp" line="116"/> + <source>Help</source> +- <translation>རོགས་རམ་བྱེད་པ།</translation> ++ <translation type="vanished">རོགས་རམ་བྱེད་པ།</translation> + </message> + <message> +- <location filename="../krightwidget.cpp" line="101"/> +- <location filename="../krightwidget.cpp" line="108"/> +- <source>About</source> +- <translation>འབྲེལ་ཡོད་ཀྱི་སྐོར།</translation> +- </message> +- <message> +- <location filename="../krightwidget.cpp" line="102"/> +- <location filename="../krightwidget.cpp" line="124"/> +- <source>Exit</source> +- <translation>ཕྱིར་འཐེན་བྱེད་པ།</translation> +- </message> +- <message> +- <location filename="../krightwidget.cpp" line="111"/> + <location filename="../krightwidget.cpp" line="112"/> ++ <location filename="../krightwidget.cpp" line="113"/> + <source>Kylin System Monitor</source> + <translation>ཅིན་ལིན་མ་ལག་ལྟ་ཞིབ་ཚད་ལེན</translation> + </message> +@@ -471,18 +459,18 @@ + <context> + <name>MemHistoryWidget</name> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="123"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="124"/> + <source>Memory</source> + <translation>དྲན་ཤེས་</translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="132"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="134"/> + <source>Swap</source> + <translation>བརྗེ་རེས་བྱེད་པ།</translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="137"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="297"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="139"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="296"/> + <source>Not enabled</source> + <translation>ནུས་པ་ཐོན་མི་ཐུབ་པ།</translation> + </message> +@@ -667,6 +655,44 @@ + <translation>སྐུར་སྐྱེལ་བྱེད་པ།</translation> + </message> + </context> ++<context> ++ <name>OnCloseDialog</name> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="12"/> ++ <source>System Monitor</source> ++ <translation>ཅིན་ལིན་མ་ལག་ལྟ་ཞིབ་ཚད་ལེན</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="36"/> ++ <source>When clicking the close button</source> ++ <translation>སྒོ་བརྒྱབ་ནས་གཅུས་སྒོ་རྒྱག་སྐབས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="41"/> ++ <source>Minimize to tray</source> ++ <translation>སྡེར་མ་ཆུང་ཤོས་སུ་འགྱུར་བ་བྱེད་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="42"/> ++ <source>Exit Application</source> ++ <translation>དངོས་སྤྱོད་ལས་ཕྱིར་འཐེན་བྱ་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="47"/> ++ <source>No more inquiries</source> ++ <translation>འདྲི་རྩད་མི་བྱེད།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="50"/> ++ <source>Cancel</source> ++ <translation>ཕྱིར་འཐེན།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="52"/> ++ <source>Confirm</source> ++ <translation>དངོས་སུ་ཁས་ལེན་པ།</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -893,24 +919,35 @@ Are you sure to continue?</source> + <context> + <name>ProcessWidget</name> + <message> +- <source>Active Processes</source> +- <translation type="vanished">འཁྲུག་ཆ་དོད་པའི་གོ་རིམ།</translation> +- </message> +- <message> +- <location filename="../process/processwidget.cpp" line="78"/> ++ <location filename="../process/processwidget.cpp" line="81"/> + <source>Applications</source> + <translation>རེ་འདུན་ཞུ་ཡིག</translation> + </message> + <message> +- <location filename="../process/processwidget.cpp" line="79"/> ++ <location filename="../process/processwidget.cpp" line="82"/> + <source>My Processes</source> + <translation>ངའི་བརྒྱུད་རིམ།</translation> + </message> + <message> +- <location filename="../process/processwidget.cpp" line="80"/> ++ <location filename="../process/processwidget.cpp" line="83"/> + <source>All Process</source> + <translation>བརྒྱུད་རིམ་ཡོད་ཚད།</translation> + </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="110"/> ++ <source>Applications(%1)</source> ++ <translation>རེ་འདུན་ཞུ་ཡིག(%1)</translation> ++ </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="111"/> ++ <source>My Processes(%1)</source> ++ <translation>ངའི་བརྒྱུད་རིམ།(%1)</translation> ++ </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="112"/> ++ <source>All Process(%1)</source> ++ <translation>བརྒྱུད་རིམ་ཡོད་ཚད།(%1)</translation> ++ </message> + </context> + <context> + <name>QObject</name> +@@ -947,7 +984,7 @@ Are you sure to continue?</source> + <message> + <location filename="../process/processtablemodel.cpp" line="57"/> + <location filename="../sysresource/commoninfo.cpp" line="440"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="39"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="40"/> + <location filename="../sysresource/nethistorywidget.cpp" line="43"/> + <source>MiB</source> + <translation>MiB</translation> +@@ -975,21 +1012,21 @@ Are you sure to continue?</source> + </message> + <message> + <location filename="../sysresource/commoninfo.cpp" line="433"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="35"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="36"/> + <location filename="../sysresource/nethistorywidget.cpp" line="36"/> + <source>KiB</source> + <translation>KiB</translation> + </message> + <message> + <location filename="../sysresource/commoninfo.cpp" line="447"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="43"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="44"/> + <location filename="../sysresource/nethistorywidget.cpp" line="50"/> + <source>GiB</source> + <translation>GiB</translation> + </message> + <message> + <location filename="../sysresource/commoninfo.cpp" line="454"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="47"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="48"/> + <location filename="../sysresource/nethistorywidget.cpp" line="57"/> + <source>TiB</source> + <translation>TiB</translation> +@@ -1456,35 +1493,68 @@ Are you sure to continue?</source> + <translation>ཞབས་ཞུའི་དངོས་པོའི་མིང་།</translation> + </message> + </context> ++<context> ++ <name>SettingDialog</name> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="15"/> ++ <source>System Monitor</source> ++ <translation>ཅིན་ལིན་མ་ལག་ལྟ་ཞིབ་ཚད་ལེན</translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="37"/> ++ <source>Exit settings</source> ++ <translation>ཕྱིར་འཐེན་བཅས་བྱ་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="42"/> ++ <source>Minimize to tray</source> ++ <translation>སྡེར་མ་ཆུང་ཤོས་སུ་འགྱུར་བ་བྱེད་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="43"/> ++ <source>Exit Application</source> ++ <translation>དངོས་སྤྱོད་ལས་ཕྱིར་འཐེན་བྱ་དགོས།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="56"/> ++ <source>Cancel</source> ++ <translation>ཕྱིར་འཐེན།</translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="58"/> ++ <source>Confirm</source> ++ <translation>དངོས་སུ་ཁས་ལེན་པ།</translation> ++ </message> ++</context> + <context> + <name>TrayIcon</name> + <message> +- <location filename="../trayicon.cpp" line="38"/> ++ <location filename="../trayicon.cpp" line="40"/> + <source>Exit</source> + <translation>ཕྱིར་འབུད་</translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="40"/> ++ <location filename="../trayicon.cpp" line="42"/> + <source>Open monitor</source> + <translation>རྒྱུད་ཁོངས་ལྟ་ཞིབ་ཆས་ཁ་འབྱེད་</translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="94"/> ++ <location filename="../trayicon.cpp" line="110"/> + <source>NET: </source> + <translation>དྲ་རྒྱ།:</translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="95"/> ++ <location filename="../trayicon.cpp" line="111"/> + <source>CPU: </source> + <translation>CPU:</translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="96"/> ++ <location filename="../trayicon.cpp" line="112"/> + <source>RAM: </source> + <translation>ནང་གསོག:</translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="112"/> ++ <location filename="../trayicon.cpp" line="128"/> + <source>Disk: </source> + <translation>སྡུད་སྡེར་:</translation> + </message> +diff --git a/src/translation/ukui-system-monitor_en_US.ts b/src/translation/ukui-system-monitor_en_US.ts +index 2c95ef5..458f904 100644 +--- a/src/translation/ukui-system-monitor_en_US.ts ++++ b/src/translation/ukui-system-monitor_en_US.ts +@@ -448,18 +448,18 @@ + <context> + <name>MemHistoryWidget</name> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="123"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="124"/> + <source>Memory</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="132"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="134"/> + <source>Swap</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../sysresource/memhistorywidget.cpp" line="137"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="297"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="139"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="296"/> + <source>Not enabled</source> + <translation type="unfinished"></translation> + </message> +@@ -641,6 +641,43 @@ + <location filename="../sysresource/netitemwidget.cpp" line="67"/> + <location filename="../sysresource/netitemwidget.cpp" line="85"/> + <source>Send</source> ++ </message> ++</context> ++<context> ++ <name>OnCloseDialog</name> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="12"/> ++ <source>System Monitor</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="36"/> ++ <source>When clicking the close button</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="41"/> ++ <source>Minimize to tray</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="42"/> ++ <source>Exit Application</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="47"/> ++ <source>No more inquiries</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="50"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/onclosedialog.cpp" line="52"/> ++ <source>Confirm</source> + <translation type="unfinished"></translation> + </message> + </context> +@@ -864,26 +901,41 @@ Are you sure to continue?</source> + <context> + <name>ProcessWidget</name> + <message> +- <location filename="../process/processwidget.cpp" line="78"/> ++ <location filename="../process/processwidget.cpp" line="81"/> + <source>Applications</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processwidget.cpp" line="79"/> ++ <location filename="../process/processwidget.cpp" line="82"/> + <source>My Processes</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../process/processwidget.cpp" line="80"/> ++ <location filename="../process/processwidget.cpp" line="83"/> + <source>All Process</source> + <translation type="unfinished"></translation> + </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="110"/> ++ <source>Applications(%1)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="111"/> ++ <source>My Processes(%1)</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../process/processwidget.cpp" line="112"/> ++ <source>All Process(%1)</source> ++ <translation type="unfinished"></translation> ++ </message> + </context> + <context> + <name>QObject</name> + <message> + <location filename="../sysresource/commoninfo.cpp" line="433"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="35"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="36"/> + <location filename="../sysresource/nethistorywidget.cpp" line="36"/> + <source>KiB</source> + <translation>KB</translation> +@@ -891,21 +943,21 @@ Are you sure to continue?</source> + <message> + <location filename="../process/processtablemodel.cpp" line="57"/> + <location filename="../sysresource/commoninfo.cpp" line="440"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="39"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="40"/> + <location filename="../sysresource/nethistorywidget.cpp" line="43"/> + <source>MiB</source> + <translation>MB</translation> + </message> + <message> + <location filename="../sysresource/commoninfo.cpp" line="447"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="43"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="44"/> + <location filename="../sysresource/nethistorywidget.cpp" line="50"/> + <source>GiB</source> + <translation>GB</translation> + </message> + <message> + <location filename="../sysresource/commoninfo.cpp" line="454"/> +- <location filename="../sysresource/memhistorywidget.cpp" line="47"/> ++ <location filename="../sysresource/memhistorywidget.cpp" line="48"/> + <location filename="../sysresource/nethistorywidget.cpp" line="57"/> + <source>TiB</source> + <translation>TB</translation> +@@ -1423,35 +1475,68 @@ Are you sure to continue?</source> + <translation type="unfinished"></translation> + </message> + </context> ++<context> ++ <name>SettingDialog</name> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="15"/> ++ <source>System Monitor</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="37"/> ++ <source>Exit settings</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="42"/> ++ <source>Minimize to tray</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="43"/> ++ <source>Exit Application</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="56"/> ++ <source>Cancel</source> ++ <translation type="unfinished"></translation> ++ </message> ++ <message> ++ <location filename="../dialog/settingdialog.cpp" line="58"/> ++ <source>Confirm</source> ++ <translation type="unfinished"></translation> ++ </message> ++</context> + <context> + <name>TrayIcon</name> + <message> +- <location filename="../trayicon.cpp" line="38"/> ++ <location filename="../trayicon.cpp" line="40"/> + <source>Exit</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="40"/> ++ <location filename="../trayicon.cpp" line="42"/> + <source>Open monitor</source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="94"/> ++ <location filename="../trayicon.cpp" line="110"/> + <source>NET: </source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="95"/> ++ <location filename="../trayicon.cpp" line="111"/> + <source>CPU: </source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="96"/> ++ <location filename="../trayicon.cpp" line="112"/> + <source>RAM: </source> + <translation type="unfinished"></translation> + </message> + <message> +- <location filename="../trayicon.cpp" line="112"/> ++ <location filename="../trayicon.cpp" line="128"/> + <source>Disk: </source> + <translation type="unfinished"></translation> + </message> +diff --git a/src/translation/ukui-system-monitor_mn.ts b/src/translation/ukui-system-monitor_mn.ts +index ef23ace..5c1ab65 100644 +--- a/src/translation/ukui-system-monitor_mn.ts ++++ b/src/translation/ukui-system-monitor_mn.ts +@@ -243,15 +243,15 @@ + </message> + <message> + <source>Help</source> +- <translation>ᠬᠠᠪᠰᠤᠷᠤᠨᠠ ᠃</translation> ++ <translation type="vanished">ᠬᠠᠪᠰᠤᠷᠤᠨᠠ ᠃</translation> + </message> + <message> + <source>About</source> +- <translation>ᠲᠤᠬᠠᠢ</translation> ++ <translation type="vanished">ᠲᠤᠬᠠᠢ</translation> + </message> + <message> + <source>Exit</source> +- <translation>ᠤᠬᠤᠷᠢᠵᠤ ᠭᠠᠷᠤᠨᠠ ᠃</translation> ++ <translation type="vanished">ᠤᠬᠤᠷᠢᠵᠤ ᠭᠠᠷᠤᠨᠠ ᠃</translation> + </message> + <message> + <source>Search</source> +@@ -541,6 +541,37 @@ + <translation>ᠢᠯᠡᠬᠡᠬᠦ᠌</translation> + </message> + </context> ++<context> ++ <name>OnCloseDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>ᠰᠢᠰᠲ᠋ᠧᠮᠲᠦ ᠬᠢᠨᠠᠨ ᠠᠵᠢᠭᠯᠠᠬᠤ ᠮᠠᠰᠢᠨ</translation> ++ </message> ++ <message> ++ <source>When clicking the close button</source> ++ <translation>ᠳᠠᠷᠤᠭᠤᠯ ᠢ ᠳᠠᠷᠤᠬᠤ ᠦᠶᠡ ᠳᠦ</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>ᠬᠠᠮᠤᠭ ᠪᠠᠭᠠ ᠪᠣᠯᠪᠠ</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>ᠬᠡᠷᠡᠭᠯᠡᠭᠡᠨ ᠡᠴᠡ ᠤᠬᠤᠷᠢᠨ ᠭᠠᠷᠤᠨᠠ</translation> ++ </message> ++ <message> ++ <source>No more inquiries</source> ++ <translation>ᠲᠠᠬᠢᠵᠤ ᠠᠰᠠᠭᠤᠬᠤ ᠦᠭᠡᠢ</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>ᠨᠤᠲᠠᠯᠠᠨ ᠲᠣᠭᠲᠠᠭᠠᠬᠤ</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -744,6 +775,18 @@ Are you sure to continue?</source> + <source>All Process</source> + <translation>ᠪᠦᠬᠦ ᠠᠬᠢᠴᠠ</translation> + </message> ++ <message> ++ <source>Applications(%1)</source> ++ <translation>ᠬᠡᠷᠡᠭᠯᠡᠭᠡᠨᠦ᠌ ᠫᠷᠤᠭ᠌ᠷᠡᠮ(%1)</translation> ++ </message> ++ <message> ++ <source>My Processes(%1)</source> ++ <translation>ᠮᠢᠨᠤ ᠠᠬᠢᠴᠠ(%1)</translation> ++ </message> ++ <message> ++ <source>All Process(%1)</source> ++ <translation>ᠪᠦᠬᠦ ᠠᠬᠢᠴᠠ(%1)</translation> ++ </message> + </context> + <context> + <name>PropertiesDialog</name> +@@ -1315,6 +1358,33 @@ Are you sure to continue?</source> + <translation>ᠡᠷᠢᠵᠦ ᠣᠯᠣᠭᠰᠠᠨ ᠦᠭᠡᠢ %1 ᠦᠢᠯᠡᠴᠢᠯᠡᠭᠡ.</translation> + </message> + </context> ++<context> ++ <name>SettingDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>ᠰᠢᠰᠲ᠋ᠧᠮᠲᠦ ᠬᠢᠨᠠᠨ ᠠᠵᠢᠭᠯᠠᠬᠤ ᠮᠠᠰᠢᠨ</translation> ++ </message> ++ <message> ++ <source>Exit settings</source> ++ <translation>ᠪᠤᠴᠠᠭᠠᠵᠤ ᠭᠠᠷᠭᠠᠬᠤ ᠪᠠᠶᠢᠷᠢᠯᠠᠭᠤᠯᠤᠯᠲᠠ</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>ᠬᠠᠮᠤᠭ ᠪᠠᠭᠠ ᠪᠣᠯᠪᠠ</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>ᠬᠡᠷᠡᠭᠯᠡᠭᠡᠨ ᠡᠴᠡ ᠤᠬᠤᠷᠢᠨ ᠭᠠᠷᠤᠨᠠ</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>ᠬᠦᠴᠦᠨ ᠦᠬᠡᠢ ᠪᠤᠯᠭᠠᠬᠤ</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>ᠨᠤᠲᠠᠯᠠᠨ ᠲᠣᠭᠲᠠᠭᠠᠬᠤ</translation> ++ </message> ++</context> + <context> + <name>TrayIcon</name> + <message> +diff --git a/src/translation/ukui-system-monitor_zh_CN.ts b/src/translation/ukui-system-monitor_zh_CN.ts +index 2f2a6a6..24b76f7 100644 +--- a/src/translation/ukui-system-monitor_zh_CN.ts ++++ b/src/translation/ukui-system-monitor_zh_CN.ts +@@ -251,15 +251,15 @@ + </message> + <message> + <source>Help</source> +- <translation>帮助</translation> ++ <translation type="vanished">帮助</translation> + </message> + <message> + <source>About</source> +- <translation>关于</translation> ++ <translation type="vanished">关于</translation> + </message> + <message> + <source>Exit</source> +- <translation>退出</translation> ++ <translation type="vanished">退出</translation> + </message> + <message> + <source>Search</source> +@@ -549,6 +549,37 @@ + <translation>发送</translation> + </message> + </context> ++<context> ++ <name>OnCloseDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>系统监视器</translation> ++ </message> ++ <message> ++ <source>When clicking the close button</source> ++ <translation>点击关闭按钮时</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>最小化到托盘</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>退出应用</translation> ++ </message> ++ <message> ++ <source>No more inquiries</source> ++ <translation>不再询问</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>确认</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -748,6 +779,18 @@ Are you sure to continue?</source> + <source>All Process</source> + <translation>全部进程</translation> + </message> ++ <message> ++ <source>Applications(%1)</source> ++ <translation>应用程序(%1)</translation> ++ </message> ++ <message> ++ <source>My Processes(%1)</source> ++ <translation>我的进程(%1)</translation> ++ </message> ++ <message> ++ <source>All Process(%1)</source> ++ <translation>全部进程(%1)</translation> ++ </message> + </context> + <context> + <name>PropertiesDialog</name> +@@ -1331,6 +1374,33 @@ Are you sure to continue?</source> + <translation>未找到 %1 服务。</translation> + </message> + </context> ++<context> ++ <name>SettingDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>系统监视器</translation> ++ </message> ++ <message> ++ <source>Exit settings</source> ++ <translation>退出设置</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>最小化到托盘</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>退出应用</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>确认</translation> ++ </message> ++</context> + <context> + <name>TrayIcon</name> + <message> +diff --git a/src/translation/ukui-system-monitor_zh_HK.ts b/src/translation/ukui-system-monitor_zh_HK.ts +index 510c25e..c1ba8cb 100644 +--- a/src/translation/ukui-system-monitor_zh_HK.ts ++++ b/src/translation/ukui-system-monitor_zh_HK.ts +@@ -247,15 +247,15 @@ + </message> + <message> + <source>Help</source> +- <translation>説明</translation> ++ <translation type="vanished">幫助</translation> + </message> + <message> + <source>About</source> +- <translation>關於</translation> ++ <translation type="vanished">關於</translation> + </message> + <message> + <source>Exit</source> +- <translation>退出</translation> ++ <translation type="vanished">退出</translation> + </message> + <message> + <source>Search</source> +@@ -541,6 +541,37 @@ + <translation>發送</translation> + </message> + </context> ++<context> ++ <name>OnCloseDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>系統監視器</translation> ++ </message> ++ <message> ++ <source>When clicking the close button</source> ++ <translation>點擊關閉按鈕時</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>最小化到托盤</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>退出應用</translation> ++ </message> ++ <message> ++ <source>No more inquiries</source> ++ <translation>不再詢問</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>確認</translation> ++ </message> ++</context> + <context> + <name>ProcPropertiesDlg</name> + <message> +@@ -728,6 +759,18 @@ Are you sure to continue?</source> + <source>All Process</source> + <translation>全部進程</translation> + </message> ++ <message> ++ <source>Applications(%1)</source> ++ <translation>應用程序(%1)</translation> ++ </message> ++ <message> ++ <source>My Processes(%1)</source> ++ <translation>我的進程(%1)</translation> ++ </message> ++ <message> ++ <source>All Process(%1)</source> ++ <translation>全部進程(%1)</translation> ++ </message> + </context> + <context> + <name>PropertiesDialog</name> +@@ -1303,6 +1346,33 @@ Are you sure to continue?</source> + <translation>未找到 %1 服務。</translation> + </message> + </context> ++<context> ++ <name>SettingDialog</name> ++ <message> ++ <source>System Monitor</source> ++ <translation>系統監視器</translation> ++ </message> ++ <message> ++ <source>Exit settings</source> ++ <translation>退出設置</translation> ++ </message> ++ <message> ++ <source>Minimize to tray</source> ++ <translation>最小化到托盤</translation> ++ </message> ++ <message> ++ <source>Exit Application</source> ++ <translation>退出應用</translation> ++ </message> ++ <message> ++ <source>Cancel</source> ++ <translation>取消</translation> ++ </message> ++ <message> ++ <source>Confirm</source> ++ <translation>確認</translation> ++ </message> ++</context> + <context> + <name>TrayIcon</name> + <message> +diff --git a/src/trayicon.cpp b/src/trayicon.cpp +index 965e404..5f48955 100644 +--- a/src/trayicon.cpp ++++ b/src/trayicon.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include "trayicon.h" + + #include <KWindowSystem> +@@ -49,7 +68,7 @@ void TrayIcon::initMenu() + void TrayIcon::initConnect() + { + connect(mQuitAction, &QAction::triggered, this, [=](){ +- window()->close(); ++ Q_EMIT needSaveSetting(); + qApp->exit(); + }); + +diff --git a/src/trayicon.h b/src/trayicon.h +index 38e0744..f1aa17e 100644 +--- a/src/trayicon.h ++++ b/src/trayicon.h +@@ -39,6 +39,7 @@ public slots: + + signals: + void openMonitor(const QString &); ++ void needSaveSetting(); + + }; + +diff --git a/tests/main.cpp b/tests/main.cpp +index 7196885..6981ecf 100644 +--- a/tests/main.cpp ++++ b/tests/main.cpp +@@ -1,3 +1,22 @@ ++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- ++ * ++ * Copyright (C) 2024 KylinSoft Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ * ++ */ + #include <gtest/gtest.h> + + int main(int argc, char **argv) diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/0039-fix-main-using-kdk.patch ukui-system-monitor-4.20.0.0/debian/patches/0039-fix-main-using-kdk.patch --- ukui-system-monitor-4.10.0.0/debian/patches/0039-fix-main-using-kdk.patch 1970-01-01 08:00:00.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/0039-fix-main-using-kdk.patch 2024-11-19 17:11:36.000000000 +0800 @@ -0,0 +1,27 @@ +From: hesisheng <hesisheng@kylinos.cn> +Date: Thu, 6 Mar 2025 17:13:54 +0800 +Subject: fix(main): using kdk +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +Description: using KDK_USE_WAYLAND_BRIDGE + +Log: 系统监视器中的应用程序不显示播放器进程 +Bug: https://pm.kylin.com/bug-view-329897.html +--- + src/main.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/main.cpp b/src/main.cpp +index af3dab4..2c8f6b3 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -105,6 +105,7 @@ static void registerSignals() + int main(int argc, char *argv[]) + { + qputenv("QT_QPA_PLATFORMTHEME",QByteArray("ukui")); ++ qputenv("KDK_USE_WAYLAND_BRIDGE", "1"); + + registerSignals(); + initUkuiLog4qt("ukui-system-monitor"); diff -Nru ukui-system-monitor-4.10.0.0/debian/patches/series ukui-system-monitor-4.20.0.0/debian/patches/series --- ukui-system-monitor-4.10.0.0/debian/patches/series 2024-07-25 15:52:05.000000000 +0800 +++ ukui-system-monitor-4.20.0.0/debian/patches/series 2024-11-19 17:11:36.000000000 +0800 @@ -32,3 +32,8 @@ 0032-update-ukui-system-monitor.desktop.patch 0033-Translated-using-Weblate-Mongolian.patch 0034-Translated-using-Weblate-Mongolian.patch +0035-50-changelog.patch +0036-54-nile.patch +0037-56-fix-sonar-security.patch +0038-57-fix-debug-add-debug.patch +0039-fix-main-using-kdk.patch