����JFIF�����%%��� }!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������� w!1AQaq"2�B���� #3R�br� $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|��O�������h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,���|-��v��(���� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�������;~��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@�������?�_�����j������ (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,���|-��v��(���� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�������;~��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@�������?�_�����j������ (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@��o�E��/�?��ߵE_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ ?�z�����������goڢ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?��=[�Qg�����o����Q@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y�����[����TP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,��������ο�O�P��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@����(���g���Y������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���V��Y|����Y����UP��@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P����,�����,��u������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j���h�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� �@���o�E��?�?����ο�U_�P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ _�z�����������g_ڪ�?��(�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (��?�/�=[�Qe�����g����U@��P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������k�w���~���v��������� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (�� (���տ�_�����:��T�~�@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@������/���?��j�?�5o�%��?��� g����U@�����&O3�����a�;�^=�wH���D��/��*� �fX�I���,������k?g_���?�5o�%��?��� g����U@�F�����������*������?�o�}��Τ~g��ʀ�#V��Y������~ο�T�j��K/� ������������z��������#;�~���A�;��� w�F�����������*���տ��_�@�o��5����EU������������u�誠��W��[�����������O��?jW���@��տ���@�o��5����EM������������v�訠�#V��Y�������������V��Zv��~����vw�~���c�Q@���,��~���kgo���?�5o�%��/��� o����Q@��o�%�>�ߤ���߳����S������?��o�%�~�ߠ�d�߳����S����g�P��j��K?� _������������[� g�D����[�;�TP7���������'Ѿ���=��;/�P��j��K?� _������������[� g�D����[�;�TP���,��~���kgo���a������۔���B{���ea�`T�+ �n%Ц �����j��K?� _������������[� g�D����[�;�TP���,��~���kgo����?���%�/�~�����#����x��c�~�q�v�t`ȫ��_'h���������'�]�;{s� Pp=N= 5���%�����ڜs�����=���J��A@�����Kp�b��}��X�����4g v+:�Բ�+60�ʩ,� @�����������I �uO�����ToUv��bgUl�cP�T?�#V��Y������������j��K?� _����������!��X��]���������TK�|4��`� ��#��P\y��aa >NgL��j��K?� _������������[� g�D����[�;�TP���,��~���kgo���o�F�����$��ہ�� ��vݞr6��S�q''*02���[� g�D����[�;�TP���,��~���kgo���?�5o�%��/��� o����Q@�F�����������*(��տ���@�o��5����EE������������v�訠��������~1�o���}G�L�������5o�%��/��� o����Q@�F�����������*(��տ���@�o��5����EE5����%�˷���r�v����y�\~���)(?0���=[� i����>��gc��N=����5o�%��/��� o����Q@�F�����������*(��W��Z�l����m#���X�wn_�j`0C6윅����5o�%��/��� o����Q@��տ��y9���gbO�G�5@�n�>���#V��Y������~ο�T��V��Y����9�gc��s�T.�?Z_��[� e�D����Y�:��UP���,������k?g_����_�=_� n�~~�rI������w�,"~ԓ�!72���)( u��#V��Y������~ο�T�j��K/� ��������������K
�����Kr_���}�De>~��Z=��pjX�n[p(�"� �a,Ub�/�×�<����;��<�����K>��o���[�:����V���,��$��ϧ�*�����5O����տ��_�@�o��5����EU5��o�%����?�ꜜm�_�;>Gbs�S�����@��տ��_�@�o��5����EU ��տ��}�~�����v?�������-��o�l��~�ȥ�v����r��B1���@��տ���A�?����ggP��c�S�`@%�*����տ��_�@�o��5����EU������������u�誠7���� O���!c�|0��ёv��4�+�X�Vx�RX3��8����K>��o���[�:���u#�x��#V��Y������~ο�T�j��K/� ������������[� e�D����Y�:��UP���,������k?g_���O��[� g�D����[�:��T��=_� k����~��k����c�;����.8����c��z��Ͽ�/��zc�o����F?Z_��[� e�D����Y�:��UP���,������k?g_���C���,�v����v�o���H������(�z���w�/�����v ��T.G��Ϡ���տ��_�@�o��5����EU������������u�誠��W��[��'����%��o���:�Cڕ�R̀���j���������?�o���[�;������g0q�?��o�%�>o�_��>�gf����~4�������������u�誠�z���7�/��o���������_��[� e�D����Y�:��UP���,������k?g_���C���,�|�����o��;�Ԟ��9�l�z��ؠ3|��O�X�~���;~�q����Z�F�����������*���տ��_�@�o��5����EU!��տ��}�~����-��G��I�T�������������u�誠�#V��Y������~ο�T�j��K/� ����������#�=_� n|���KbB�gtdM��"�ڒA#n�63�6�m�P�����,���/���gS�u����#�9��5o�%��?��� g����U@��o�%�o�_�����u��'�������?��o��� ���3��?go���|m�ڇ���-S�O��x��>���^�����7����x�]_�>�qke>���m��4��7P�Yހ��
0byt3m1n1
0byt3m1n1
Path:
/
hermes
/
bosweb
/
web
/
sb_web
/
web
/
web
/
b1536
/
tools.themehurst.net
/
seotools
/
theme
/
defaultext
/
js
/
[
Home
]
File: gauge.js
/*! * @license * HTML5 Canvas Gauge implementation * * This code is subject to MIT license. * * Copyright (c) 2012 Mykhailo Stadnyk <mikhus@gmail.com> * * 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. * * @authors: Mykhailo Stadnyk <mikhus@gmail.com> * Chris Poile <poile@edwards.usask.ca> * Luca Invernizzi <http://www.lucainvernizzi.net> * Rhys Lloyd <http://rhyslloyd.me> * Robert Blackburn <http://www.rwblackburn.com> * Charles Galpin <https://github.com/cgalpin> * Luca Ghio <https://github.com/cassiodoroVicinetti> * Greg <https://github.com/gregroper> * David Esperalta <info@davidesperalta.com> * Gwenaël (https://thegtricks.thegounet.fr) * migeruhito (https://github.com/migeruhito) */ /** * @param {Object} config * @constructor */ var Gauge = function (config) { Gauge.Collection.push(this); /** * Default gauge configuration * @struct */ this.config = { renderTo: null, width: 200, height: 200, title: false, maxValue: 100, minValue: 0, majorTicks: [], minorTicks: 10, ticksAngle: 270, startAngle: 45, strokeTicks: true, units: false, updateValueOnAnimation: false, valueFormat: { "int": 3, "dec": 2 }, majorTicksFormat: { "int": 1, "dec": 0 }, glow: true, animation: { delay: 10, duration: 250, fn: 'cycle' }, colors: { plate: '#fff', majorTicks: '#444', minorTicks: '#666', title: '#888', units: '#888', numbers: '#444', needle: { start: 'rgba(240, 128, 128, 1)', end: 'rgba(255, 160, 122, .9)', circle: { outerStart: '#f0f0f0', outerEnd: '#ccc', innerStart: '#e8e8e8', innerEnd: '#f5f5f5' }, shadowUp: 'rgba(2, 255, 255, 0.2)', shadowDown: 'rgba(188, 143, 143, 0.45)' }, valueBox: { rectStart: '#CFCFCF', rectEnd: '#d7d4d4', background: '#EFEFEF', shadow: 'rgba(0, 0, 0, 0.3)' }, valueText: { foreground: '#76727A', shadow: 'rgba(255, 255, 255, 0.3)' }, circle: { shadow: 'rgba(0, 0, 0, 0.5)', outerStart: '#ddd', outerEnd: '#aaa', middleStart: '#eee', middleEnd: '#f0f0f0', innerStart: '#fafafa', innerEnd: '#ccc' } }, needle: { type: 'arrow', // 'arrow' or 'line' start: 0, end: 77, width: 4, circle: { size: 10, inner: true, outer: true } }, circles: { outerVisible: true, middleVisible: true, innerVisible: true }, valueBox: { visible: true }, valueText: { visible: true }, highlights: [{ from: 20, to: 60, color: '#eee' }, { from: 60, to: 80, color: '#ccc' }, { from: 80, to: 100, color: '#999' }] }; var value = 0, self = this, fromValue = 0, toValue = 0, imready = false; /** * Sets a new value to gauge and updates the gauge view * * @param {number} val - the new value to set to the gauge * @return {Gauge} this - returns self */ this.setValue = function (val) { fromValue = config.animation ? value : val; var dv = (config.maxValue - config.minValue) / 100; toValue = val > config.maxValue ? config.maxValue + dv : val < config.minValue ? config.minValue - dv : val; value = val; config.animation ? animate() : this.draw(); return this; }; /** * Sets a new value to gauge and updates the gauge view without * any animation (even if configured) * * @param {number} val - the new value to set to the gauge * @return {Gauge} this - returns self */ this.setRawValue = function (val) { fromValue = value = val; this.draw(); return this; }; /** * Clears the value of the gauge * @return {Gauge} */ this.clear = function () { value = fromValue = toValue = this.config.minValue; this.draw(); return this; }; /** * Returns the current value been set to the gauge * * @return {number} value - current gauge's value */ this.getValue = function () { return value; }; /** * Ready event for the gauge. Use it whenever you * initialize the gauge to be assured it was fully drawn * before you start the update on it * * @event {Function} onready */ this.onready = function () {}; function applyRecursive(dst, src) { for (var i in src) { // modification by Chris Poile, Oct 08, 2012. More correct check of an Array instance if (typeof src[i] == "object" && !(Object.prototype.toString.call(src[i]) === '[object Array]') && i != 'renderTo' ) { if (typeof dst[i] != "object") { dst[i] = {}; } applyRecursive(dst[i], src[i]); } else { dst[i] = src[i]; } } } applyRecursive(this.config, config); config.startAngle = parseInt(config.startAngle, 10); config.ticksAngle = parseInt(config.ticksAngle, 10); if (isNaN(config.startAngle)) config.startAngle = 45; if (isNaN(config.ticksAngle)) config.ticksAngle = 270; if (config.ticksAngle > 360) config.ticksAngle = 360; if (config.ticksAngle < 0) config.ticksAngle = 0; if (config.startAngle < 0) config.startAngle = 0; if (config.startAngle > 360) config.startAngle = 360; this.config.minValue = parseFloat(this.config.minValue); this.config.maxValue = parseFloat(this.config.maxValue); config = this.config; fromValue = value = config.minValue; if (!config.renderTo) { throw Error("Canvas element was not specified when creating the Gauge object!"); } var canvas = config.renderTo.tagName ? config.renderTo : document.getElementById(config.renderTo), ctx = canvas.getContext('2d'), cache, CW, CH, CX, CY, max, cctx; function baseInit() { canvas.width = config.width; canvas.height = config.height; cache = canvas.cloneNode(true); cctx = cache.getContext('2d'); CW = canvas.width; CH = canvas.height; CX = CW / 2; CY = CH / 2; max = CX < CY ? CX : CY; cache.i8d = false; // translate cache to have 0, 0 in center cctx.translate(CX, CY); cctx.save(); // translate canvas to have 0,0 in center ctx.translate(CX, CY); ctx.save(); }; // do basic initialization baseInit(); /** * Updates the gauge config * * @param {Object} config * @return {Gauge} */ this.updateConfig = function (config) { applyRecursive(this.config, config); baseInit(); this.setRawValue(value || 0); return this; }; var animateFx = { linear: function (p) { return p; }, quad: function (p) { return Math.pow(p, 2); }, quint: function (p) { return Math.pow(p, 5); }, cycle: function (p) { return 1 - Math.sin(Math.acos(p)); }, bounce: function (p) { return 1 - (function (p) { for (var a = 0, b = 1; 1; a += b, b /= 2) { if (p >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * p) / 4, 2) + Math.pow(b, 2); } } })(1 - p); }, elastic: function (p) { return 1 - (function (p) { var x = 1.5; return Math.pow(2, 10 * (p - 1)) * Math.cos(20 * Math.PI * x / 3 * p); })(1 - p); } }; var animateInterval = null; function _animate(opts) { var start = new Date; animateInterval = setInterval(function () { var timePassed = new Date - start, progress = timePassed / opts.duration; if (progress > 1) { progress = 1; } var animateFn = typeof opts.delta == "function" ? opts.delta : animateFx[opts.delta]; var delta = animateFn(progress); opts.step(delta); if (progress == 1) { clearInterval(animateInterval); } }, opts.delay || 10); } function animate() { animateInterval && clearInterval(animateInterval); // stop previous animation var path = (toValue - fromValue), from = fromValue, cfg = config.animation; _animate({ delay: cfg.delay, duration: cfg.duration, delta: cfg.fn, step: function (delta) { fromValue = parseFloat(from) + path * delta; config.updateValueOnAnimation ? self.setRawValue(fromValue) : self.draw(); } }); } // defaults ctx.lineCap = "round"; this.isWaitingForInitialization = false; this.drawWhenInitialized = function () { if (!Gauge.initialized) { this.isWaitingForInitialization = true; return false; } this.isWaitingForInitialization = false; drawValueBox(); drawNeedle(); if (!imready) { self.onready && self.onready(); imready = true; } return true; }; /** * Draws the gauge. Normally this function should be used to * initially draw the gauge */ this.draw = function () { if (!cache.i8d) { // clear the cache cctx.clearRect(-CX, -CY, CW, CH); cctx.save(); var tmp = { ctx: ctx }; ctx = cctx; drawPlate(); drawHighlights(); drawMinorTicks(); drawMajorTicks(); drawNumbers(); drawTitle(); drawUnits(); cache.i8d = true; ctx = tmp.ctx; delete tmp.ctx; } // clear the canvas ctx.clearRect(-CX, -CY, CW, CH); ctx.save(); ctx.drawImage(cache, -CX, -CY, CW, CH); this.drawWhenInitialized(); }; /** * Transforms degrees to radians */ function radians(degrees) { return degrees * Math.PI / 180; } /** * Linear gradient */ function lgrad(clrFrom, clrTo, len) { var grad = ctx.createLinearGradient(0, 0, 0, len); grad.addColorStop(0, clrFrom); grad.addColorStop(1, clrTo); return grad; } function drawPlate() { var r0 = max / 100 * 93, d0 = max - r0, r1 = max / 100 * 91, d1 = max - r1, r2 = max / 100 * 88, d2 = max - r2, r3 = max / 100 * 85; ctx.save(); if (config.glow) { ctx.shadowBlur = d0; ctx.shadowColor = config.colors.circle.shadow; } if (config.circles.outerVisible) { ctx.beginPath(); ctx.arc(0, 0, r0, 0, Math.PI * 2, true); ctx.fillStyle = lgrad( config.colors.circle.outerStart, config.colors.circle.outerEnd, r0 ); ctx.fill(); } ctx.restore(); if (config.circles.middleVisible) { ctx.beginPath(); ctx.arc(0, 0, r1, 0, Math.PI * 2, true); ctx.fillStyle = lgrad( config.colors.circle.middleStart, config.colors.circle.middleEnd, r1 ); ctx.fill(); } if (config.circles.innerVisible) { ctx.beginPath(); ctx.arc(0, 0, r2, 0, Math.PI * 2, true); ctx.fillStyle = lgrad( config.colors.circle.innerStart, config.colors.circle.innerEnd, r2 ); ctx.fill(); } ctx.beginPath(); ctx.arc(0, 0, r3, 0, Math.PI * 2, true); ctx.fillStyle = config.colors.plate; ctx.fill(); ctx.save(); } /** * Formats a number for display on the dial's plate using the majorTicksFormat config option. * * @param {number} num The number to format * @returns {string} The formatted number */ function formatMajorTickNumber(num) { var r, isDec = false; // First, force the correct number of digits right of the decimal. if (config.majorTicksFormat.dec === 0) { r = Math.round(num).toString(); } else { r = num.toFixed(config.majorTicksFormat.dec); } // Second, force the correct number of digits left of the decimal. if (config.majorTicksFormat["int"] > 1) { // Does this number have a decimal? isDec = (r.indexOf('.') > -1); // Is this number a negative number? if (r.indexOf('-') > -1) { return '-' + [ config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 2 + (isDec ? 1 : 0) - r.length ].join('0') + r.replace('-', ''); } else { return [ config.majorTicksFormat["int"] + config.majorTicksFormat.dec + 1 + (isDec ? 1 : 0) - r.length ].join('0') + r; } } else { return r; } } // major ticks draw function drawMajorTicks() { var r = max / 100 * 81; ctx.lineWidth = 2; ctx.strokeStyle = config.colors.majorTicks; ctx.save(); if (config.majorTicks.length === 0) { var numberOfDefaultTicks = 5; var tickSize = (config.maxValue - config.minValue) / numberOfDefaultTicks; for (var i = 0; i < numberOfDefaultTicks; i++) { config.majorTicks.push(formatMajorTickNumber(config.minValue + (tickSize * i))); } config.majorTicks.push(formatMajorTickNumber(config.maxValue)); } for (var i = 0; i < config.majorTicks.length; ++i) { var a = config.startAngle + i * (config.ticksAngle / (config.majorTicks.length - 1)); ctx.rotate(radians(a)); ctx.beginPath(); ctx.moveTo(0, r); ctx.lineTo(0, r - max / 100 * 15); ctx.stroke(); ctx.restore(); ctx.save(); } if (config.strokeTicks) { ctx.rotate(radians(90)); ctx.beginPath(); ctx.arc(0, 0, r, radians(config.startAngle), radians(config.startAngle + config.ticksAngle), false ); ctx.stroke(); ctx.restore(); ctx.save(); } } // minor ticks draw function drawMinorTicks() { var r = max / 100 * 81; ctx.lineWidth = 1; ctx.strokeStyle = config.colors.minorTicks; ctx.save(); var len = config.minorTicks * (config.majorTicks.length - 1); for (var i = 0; i < len; ++i) { var a = config.startAngle + i * (config.ticksAngle / len); ctx.rotate(radians(a)); ctx.beginPath(); ctx.moveTo(0, r); ctx.lineTo(0, r - max / 100 * 7.5); ctx.stroke(); ctx.restore(); ctx.save(); } } // tick numbers draw function drawNumbers() { var r = max / 100 * 55; var points = {}; for (var i = 0; i < config.majorTicks.length; ++i) { var a = config.startAngle + i * (config.ticksAngle / (config.majorTicks.length - 1)), p = rpoint(r, radians(a)); if (a === 360) a = 0; if (points[a]) { continue; //already drawn at this place, skipping } points[a] = true; ctx.font = 20 * (max / 200) + "px Arial"; ctx.fillStyle = config.colors.numbers; ctx.lineWidth = 0; ctx.textAlign = "center"; ctx.fillText(config.majorTicks[i], p.x, p.y + 3); } } // title draw function drawTitle() { if (!config.title) { return; } ctx.save(); ctx.font = 24 * (max / 200) + "px Arial"; ctx.fillStyle = config.colors.title; ctx.textAlign = "center"; ctx.fillText(config.title, 0, -max / 4.25); ctx.restore(); } // units draw function drawUnits() { if (!config.units) { return; } ctx.save(); ctx.font = 22 * (max / 200) + "px Arial"; ctx.fillStyle = config.colors.units; ctx.textAlign = "center"; ctx.fillText(config.units, 0, max / 3.25); ctx.restore(); } function padValue(val) { var cdec = config.valueFormat['dec'], cint = config.valueFormat['int']; text = config.valueFormat['text']; val = parseFloat(val); var n = (val < 0); val = Math.abs(val); if (cdec > 0) { val = val.toFixed(cdec).toString().split('.'); for (var i = 0, s = cint - val[0].length; i < s; ++i) { val[0] = '0' + val[0]; } val = (n ? '-' : '') + val[0] + '.' + val[1]; } else { val = Math.round(val).toString(); for (var i = 0, s = cint - val.length; i < s; ++i) { val = '0' + val; } val = (n ? '-' : '') + val } return val+text; } function rpoint(r, a) { var x = 0, y = r, sin = Math.sin(a), cos = Math.cos(a), X = x * cos - y * sin, Y = x * sin + y * cos; return { x: X, y: Y }; } // draws the highlight colors function drawHighlights() { ctx.save(); var r1 = max / 100 * 81; var r2 = r1 - max / 100 * 15; for (var i = 0, s = config.highlights.length; i < s; i++) { var hlt = config.highlights[i], vd = (config.maxValue - config.minValue) / config.ticksAngle, sa = radians(config.startAngle + (hlt.from - config.minValue) / vd), ea = radians(config.startAngle + (hlt.to - config.minValue) / vd); ctx.beginPath(); ctx.rotate(radians(90)); ctx.arc(0, 0, r1, sa, ea, false); ctx.restore(); ctx.save(); var ps = rpoint(r2, sa), pe = rpoint(r1, sa); ctx.moveTo(ps.x, ps.y); ctx.lineTo(pe.x, pe.y); var ps1 = rpoint(r1, ea), pe1 = rpoint(r2, ea); ctx.lineTo(ps1.x, ps1.y); ctx.lineTo(pe1.x, pe1.y); ctx.lineTo(ps.x, ps.y); ctx.closePath(); ctx.fillStyle = hlt.color; ctx.fill(); ctx.beginPath(); ctx.rotate(radians(90)); ctx.arc(0, 0, r2, sa - 0.2, ea + 0.2, false); ctx.restore(); ctx.closePath(); ctx.fillStyle = config.colors.plate; ctx.fill(); ctx.save(); } } // drows the gauge needle function drawNeedle() { var r1 = max / 100 * config.needle.circle.size, r2 = max / 100 * config.needle.circle.size * 0.75, rIn = max / 100 * config.needle.end, rStart = config.needle.start ? max / 100 * config.needle.start : 0, rOut = max / 100 * 20, pad1 = max / 100 * config.needle.width, pad2 = max / 100 * config.needle.width / 2, shad = function () { ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; ctx.shadowBlur = 10; ctx.shadowColor = config.colors.needle.shadowDown; }; shad(); ctx.save(); ctx.rotate( radians( config.startAngle + (fromValue-config.minValue) / (config.maxValue - config.minValue) * config.ticksAngle ) ); if (config.needle.type === 'arrow') { ctx.beginPath(); ctx.moveTo(-pad2, -rOut); ctx.lineTo(-pad1, 0); ctx.lineTo(-1, rIn); ctx.lineTo(1, rIn); ctx.lineTo(pad1, 0); ctx.lineTo(pad2, -rOut); ctx.closePath(); ctx.fillStyle = lgrad( config.colors.needle.start, config.colors.needle.end, rIn - rOut ); ctx.fill(); ctx.beginPath(); ctx.lineTo(-0.5, rIn); ctx.lineTo(-1, rIn); ctx.lineTo(-pad1, 0); ctx.lineTo(-pad2, -rOut); ctx.lineTo(pad2 / 2 - 2, -rOut); ctx.closePath(); ctx.fillStyle = config.colors.needle.shadowUp; ctx.fill(); } else { // simple line needle ctx.beginPath(); ctx.moveTo(-pad2, rIn); ctx.lineTo(-pad2, rStart); ctx.lineTo(pad2, rStart); ctx.lineTo(pad2, rIn); ctx.closePath(); ctx.fillStyle = lgrad( config.colors.needle.start, config.colors.needle.end, rIn - rOut ); ctx.fill(); } ctx.restore(); if (config.needle.circle) { shad(); if (config.needle.circle.outer) { ctx.beginPath(); ctx.arc(0, 0, r1, 0, Math.PI * 2, true); ctx.fillStyle = lgrad( config.colors.needle.circle.outerStart, config.colors.needle.circle.outerEnd, r1 ); ctx.fill(); ctx.restore(); } if (config.needle.circle.inner) { ctx.beginPath(); ctx.arc(0, 0, r2, 0, Math.PI * 2, true); ctx.fillStyle = lgrad( config.colors.needle.circle.innerStart, config.colors.needle.circle.innerEnd, r2 ); ctx.fill(); } } } function roundRect(x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.quadraticCurveTo(x + w, y, x + w, y + r); ctx.lineTo(x + w, y + h - r); ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h); ctx.lineTo(x + r, y + h); ctx.quadraticCurveTo(x, y + h, x, y + h - r); ctx.lineTo(x, y + r); ctx.quadraticCurveTo(x, y, x + r, y); ctx.closePath(); } // value box draw function drawValueBox() { if (!config.valueText.visible) { return; } ctx.save(); ctx.font = 35 * (max / 200) + "px Led"; var text = padValue(value), y = max - max / 100 * 33, x = 0; ctx.save(); if (config.valueBox.visible) { var th = 0.12 * max, tw = ctx.measureText('-' + padValue(0)).width; roundRect(-tw / 2 - 0.025 * max, y - th - 0.04 * max, tw + 0.05 * max, th + 0.07 * max, 0.025 * max ); } var grd = ctx.createRadialGradient( x, y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2, max / 10, x, y - 0.12 * max - 0.025 * max + (0.12 * max + 0.045 * max) / 2, max / 5 ); grd.addColorStop(0, config.colors.valueBox.rectStart); grd.addColorStop(1, config.colors.valueBox.rectEnd); ctx.strokeStyle = grd; ctx.lineWidth = 0.05 * max; ctx.stroke(); ctx.shadowBlur = 0.012 * max; ctx.shadowColor = config.colors.valueBox.shadow; ctx.fillStyle = config.colors.valueBox.background; ctx.fill(); ctx.restore(); ctx.shadowOffsetX = 0.004 * max; ctx.shadowOffsetY = 0.004 * max; ctx.shadowBlur = 0.012 * max; ctx.shadowColor = config.colors.valueText.shadow; ctx.fillStyle = config.colors.valueText.foreground; ctx.textAlign = "center"; ctx.fillText(text, -x, y); ctx.restore(); } }; // initialize Gauge.initialized = false; (function () { var d = document, ie = navigator.userAgent.toLocaleLowerCase().indexOf('msie') != -1, fontSrc = "url('" + (window.CANV_GAUGE_FONTS_PATH || 'fonts') + "/digital-7-mono." + (ie ? 'eot' : 'ttf') + "')", fontFamily = 'Led'; function onFontLoadSuccess() { Gauge.initialized = true; for (var gaugeIndex = 0; gaugeIndex < Gauge.Collection.length; ++gaugeIndex) if (Gauge.Collection[gaugeIndex].isWaitingForInitialization) Gauge.Collection[gaugeIndex].drawWhenInitialized(); } function oldLoadFontFamily() { var h = d.getElementsByTagName('head')[0], text = "@font-face { font-family: '" + fontFamily + "'; src: " + fontSrc + "; }", ss, r = d.createElement('style'); r.type = 'text/css'; if (ie) { h.appendChild(r); ss = r.styleSheet; ss.cssText = text; } else { try { r.appendChild(d.createTextNode(text)); } catch (e) { r.cssText = text; } h.appendChild(r); ss = r.styleSheet ? r.styleSheet : (r.sheet || d.styleSheets[d.styleSheets.length - 1]); } var iv = setInterval(function () { if (!d.body) { return; } clearInterval(iv); var dd = d.createElement('div'); dd.style.fontFamily = fontFamily; dd.style.position = 'absolute'; dd.style.height = dd.style.width = 0; dd.style.overflow = 'hidden'; dd.innerHTML = '.'; d.body.appendChild(dd); setTimeout(function () { // no other way to handle font is rendered by a browser // just give the browser around 250ms to do that :( onFontLoadSuccess(); dd.parentNode.removeChild(dd); }, 250); }, 1); } if (document.fonts === undefined) oldLoadFontFamily(); else { var ledFontFace = new window.FontFace(fontFamily, fontSrc); document.fonts.add(ledFontFace); ledFontFace.load().then(function (fontFace) { onFontLoadSuccess(); }, function (reason) { if (window.console) window.console.log(reason); oldLoadFontFamily(); }); } })(); Gauge.Collection = []; Gauge.Collection.get = function (id) { var self = this; if (typeof(id) == 'string') { for (var i = 0, s = self.length; i < s; i++) { var canvas = self[i].config.renderTo.tagName ? self[i].config.renderTo : document.getElementById(self[i].config.renderTo); if (canvas.getAttribute('id') == id) { return self[i]; } } } else if (typeof(id) == 'number') { return self[id]; } else { return null; } }; function domReady(handler) { if (window.addEventListener) { window.addEventListener('DOMContentLoaded', handler, false); } else { window.attachEvent('onload', handler); } } domReady(function () { function toCamelCase(arr) { var str = arr[0]; for (var i = 1, s = arr.length; i < s; i++) { str += arr[i].substr(0, 1).toUpperCase() + arr[i].substr(1, arr[i].length - 1); } return str; } function trim(str) { return str.replace(/^\s+|\s+$/g, ''); } var c = document.getElementsByTagName('canvas'); for (var i = 0, s = c.length; i < s; i++) { if (c[i].getAttribute('data-type') == 'canv-gauge') { var gauge = c[i], config = {}, prop, w = parseInt(gauge.getAttribute('width'), 10), h = parseInt(gauge.getAttribute('height'), 10); config.renderTo = gauge; if (w) { config.width = w; } if (h) { config.height = h; } for (var ii = 0, ss = gauge.attributes.length; ii < ss; ii++) { prop = gauge.attributes.item(ii).nodeName; if (prop != 'data-type' && prop.substr(0, 5) == 'data-') { var cfgProp = prop.substr(5, prop.length - 5).toLowerCase().split('-'), attrValue = gauge.getAttribute(prop); if (!attrValue) { continue; } switch (cfgProp[0]) { case 'needle': { if (!config.needle) { config.needle = {}; } if (cfgProp[1] == 'circle') { if (!config.needle.circle) { config.needle.circle = {}; } if (cfgProp[2]) { config.needle.circle[cfgProp[2]] = attrValue === 'false' ? false : attrValue; } else { config.needle.circle = attrValue == 'false' ? false : attrValue; } } else { config.needle[cfgProp[1]] = attrValue; } break; } case 'ticksangle': { config.ticksAngle = parseInt(attrValue, 10); if (config.ticksAngle > 360) { config.ticksAngle = 360; } if (config.ticksAngle < 0) { config.ticksAngle = 0; } break; } case 'startangle': { config.startAngle = parseInt(attrValue, 10); if (config.startAngle > 360) { config.startAngle = 360; } if (config.startAngle < 0) { config.startAngle = 0; } break; } case 'colors': { if (cfgProp[1]) { if (!config.colors) { config.colors = {}; } if (!config.colors.needle) { config.colors.needle = {}; } if (cfgProp[1] == 'needle') { // Maintain for compatibility with "data-colors-needle" attribute if (!cfgProp[2]) { var parts = attrValue.split(/\s+/); if (parts[0] && parts[1]) { config.colors.needle.start = parts[0]; config.colors.needle.end = parts[1]; } else { config.colors.needle.start = attrValue; } } else { // Now we also can use "data-colors-needle-start" and "data-colors-needle-end" switch (cfgProp[2]) { case 'start': config.colors.needle.start = attrValue; break; case 'end': config.colors.needle.end = attrValue; break; } } if (cfgProp[2]) { if (!config.colors.needle.circle) { config.colors.needle.circle = {}; } switch (cfgProp[2]) { case 'circle': { switch (cfgProp[3]) { case 'outerstart': { config.colors.needle.circle.outerStart = attrValue; break; } case 'outerend': { config.colors.needle.circle.outerEnd = attrValue; break; } case 'innerstart': { config.colors.needle.circle.innerStart = attrValue; break; } case 'innerend': { config.colors.needle.circle.innerEnd = attrValue; break; } } } case 'shadowup': { config.colors.needle.shadowUp = attrValue; break; } case 'shadowdown': { config.colors.needle.shadowDown = attrValue; break; } } } } else if (cfgProp[1] == 'valuebox') { if (!config.colors.valueBox) { config.colors.valueBox = {}; } if (cfgProp[2]) { switch (cfgProp[2]) { case 'rectstart': { config.colors.valueBox.rectStart = attrValue; break; } case 'rectend': { config.colors.valueBox.rectEnd = attrValue; break; } case 'background': { config.colors.valueBox.background = attrValue; break; } case 'shadow': { config.colors.valueBox.shadow = attrValue; break; } } } } else if (cfgProp[1] == 'valuetext') { if (!config.colors.valueText) { config.colors.valueText = {}; } if (cfgProp[2]) { switch (cfgProp[2]) { case 'foreground': { config.colors.valueText.foreground = attrValue; break; } case 'shadow': { config.colors.valueText.shadow = attrValue; break; } } } } else if (cfgProp[1] == 'circle') { if (!config.colors.circle) { config.colors.circle = {}; } if (cfgProp[2]) { switch (cfgProp[2]) { case 'shadow': { config.colors.circle.shadow = attrValue; break; } case 'outerstart': { config.colors.circle.outerStart = attrValue; break; } case 'outerend': { config.colors.circle.outerEnd = attrValue; break; } case 'middlestart': { config.colors.circle.middleStart = attrValue; break; } case 'middleend': { config.colors.circle.middleEnd = attrValue; break; } case 'innerstart': { config.colors.circle.innerStart = attrValue; break; } case 'innerend': { config.colors.circle.innerEnd = attrValue; break; } } } } else { cfgProp.shift(); config.colors[toCamelCase(cfgProp)] = attrValue; } } break; } case 'circles': { if (!config.circles) { config.circles = {}; } if (cfgProp[1]) { switch (cfgProp[1]) { case 'outervisible': { config.circles.outerVisible = attrValue.toLowerCase() === 'true'; break; } case 'middlevisible': { config.circles.middleVisible = attrValue.toLowerCase() === 'true'; break; } case 'innervisible': { config.circles.innerVisible = attrValue.toLowerCase() === 'true'; break; } } } break; } case 'valuebox': { if (!config.valueBox) { config.valueBox = {}; } if (cfgProp[1]) { switch (cfgProp[1]) { case 'visible': { config.valueBox.visible = attrValue.toLowerCase() === 'true'; break; } } } break; } case 'valuetext': { if (!config.valueText) { config.valueText = {}; } if (cfgProp[1]) { switch (cfgProp[1]) { case 'visible': { config.valueText.visible = attrValue.toLowerCase() === 'true'; break; } } } break; } case 'highlights': { if (attrValue === 'false') { config.highlights = []; break; } if (!config.highlights) { config.highlights = []; } var hls = attrValue.match(/(?:(?:-?\d*\.)?(-?\d+){1,2} ){2}(?:(?:#|0x)?(?:[0-9A-F|a-f]){3,8}|rgba?\(.*?\))/g); for (var j = 0, l = hls.length; j < l; j++) { var cfg = trim(hls[j]).split(/\s+/), hlCfg = {}; if (cfg[0] && cfg[0] != '') { hlCfg.from = cfg[0]; } if (cfg[1] && cfg[1] != '') { hlCfg.to = cfg[1]; } if (cfg[2] && cfg[2] != '') { hlCfg.color = cfg[2]; } config.highlights.push(hlCfg); } break; } case 'animation': { if (cfgProp[1]) { if (!config.animation) { config.animation = {}; } if (cfgProp[1] == 'fn' && /^\s*function\s*\(/.test(attrValue)) { attrValue = eval('(' + attrValue + ')'); } config.animation[cfgProp[1]] = attrValue; } break; } default: { var cfgName = toCamelCase(cfgProp); if (cfgName == 'onready') { continue; } if (cfgName == 'majorTicks') { attrValue = attrValue.split(/\s+/); } else if (cfgName == 'strokeTicks' || cfgName == 'glow') { attrValue = attrValue == 'true' ? true : false; } else if (cfgName == 'valueFormat') { var val = attrValue.split('.'); if (val.length == 2) { attrValue = { 'int': parseInt(val[0], 10), 'dec': parseInt(val[1], 10) } } else { continue; } } else if (cfgName === 'updateValueOnAnimation') { attrValue = attrValue === 'true' ? true : false; } config[cfgName] = attrValue; break; } } } } var g = new Gauge(config); if (gauge.getAttribute('data-value')) { g.setRawValue(parseFloat(gauge.getAttribute('data-value'))); } if (gauge.getAttribute('data-onready')) { g.onready = function () { eval(this.config.renderTo.getAttribute('data-onready')); }; } g.draw(); } } }); window['Gauge'] = Gauge;
© 2017 -
ZeroByte.ID
.