����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
/
web
/
sb_web
/
web
/
web
/
web
/
b1536
/
lycwid.com
/
ewflocaltwo.org
/
members
/
sources
/
[
Home
]
File: lang.php
<?php /* ocPortal Copyright (c) ocProducts, 2004-2012 See text/EN/licence.txt for full licencing information. NOTE TO PROGRAMMERS: Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes **** */ /** * @license http://opensource.org/licenses/cpal_1.0 Common Public Attribution License * @copyright ocProducts Ltd * @package core */ /*EXTRA FUNCTIONS: levenshtein*/ /** * Standard code module initialisation function. */ function init__lang() { if (!function_exists('do_lang')) { /** * Get the human-readable form of a language id, or a language entry from a language INI file. * * @param ID_TEXT The language id * @param ?mixed The first token [string or tempcode] (replaces {1}) (NULL: none) * @param ?mixed The second token [string or tempcode] (replaces {2}) (NULL: none) * @param ?mixed The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none) * @param ?LANGUAGE_NAME The language to use (NULL: users language) * @param boolean Whether to cause ocPortal to exit if the lookup does not succeed * @return ?mixed The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters. */ function do_lang($codename,$token1=NULL,$token2=NULL,$token3=NULL,$lang=NULL,$require_result=true) { return _do_lang($codename,$token1,$token2,$token3,$lang,$require_result); } } global $COMCODE_LANG_STRING_CACHE; $COMCODE_LANG_STRING_CACHE=array(); global $LANG; $LANG=array(); global $LANG_LOADED,$LANG_LOADED_LANG,$LANG_REQUESTED_LANG,$LANGS_REQUESTED; // Tracks what has already been require'd, although loading may have been deferred. $LANG_REQUESTED_LANG=array(); // By lang pack and lang file $LANGS_REQUESTED=array(); // Just by lang file // Tracks what has already been require'd and not deferred. This will not track all require_lang calls, as ocPortal will try and use the page's own lang cache first. $LANG_LOADED_LANG=array(); // By lang pack and lang file $LANG_LOADED=array(); // Just by lang file global $LANGUAGE; $LANGUAGE=array(); global $LANGS_MAP; $LANGS_MAP=NULL; global $USER_LANG_CACHED,$USER_LANG_EARLY_CACHED,$USER_LANG_LOOP,$REQUIRE_LANG_LOOP; global $RECORD_LANG_STRINGS,$RECORDED_LANG_STRINGS,$RECORD_LANG_STRINGS_CONTENT,$RECORDED_LANG_STRINGS_CONTENT; $RECORD_LANG_STRINGS=false; $RECORDED_LANG_STRINGS=array(); $RECORD_LANG_STRINGS_CONTENT=false; $RECORDED_LANG_STRINGS_CONTENT=array(); $USER_LANG_LOOP=0; $USER_LANG_CACHED=NULL; $USER_LANG_EARLY_CACHED=NULL; $REQUIRE_LANG_LOOP=0; global $REQUIRED_ALL_LANG; $REQUIRED_ALL_LANG=array(); // Lazy loading code: learning algorithm to cache strings against different pages without loading all, unless we get a cache miss in the page's pool global $PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED,$PAGE_CACHE_LAZY_LOAD,$PAGE_CACHE_LANGS_REQUESTED; $PAGE_CACHE_FILE=mixed(); $PAGE_CACHE_LANG_LOADED=array(); $PAGE_CACHE_LAZY_LOAD=false; $PAGE_CACHE_LANGS_REQUESTED=array(); if (((function_exists('get_option')) && (get_option('is_on_lang_cache')=='1') && ((!array_key_exists('page',$_GET)) || (/*(is_string($_GET['page'])) && */(strpos($_GET['page'],'..')===false))))/* && (!is_null($GLOBALS['MEM_CACHE']))*/) { if (running_script('index')) { $key='page__'.get_zone_name().'__'.get_page_name(); } else { $key='script__'.md5(serialize(ocp_srv('PHP_SELF'))); } $cache_path=get_custom_file_base().'/lang_cached/'.user_lang().'/'.filter_naughty($key,true).'.lcd'; if (!is_null($GLOBALS['MEM_CACHE'])) { $PAGE_CACHE_LANG_LOADED=persistent_cache_get($cache_path); if (is_array($PAGE_CACHE_LANG_LOADED)) { $PAGE_CACHE_LAZY_LOAD=true; $LANGUAGE=$PAGE_CACHE_LANG_LOADED; } $PAGE_CACHE_FILE=$cache_path; } else { $contents=@file_get_contents($cache_path); if ($contents!==false) { $PAGE_CACHE_LANG_LOADED=@unserialize($contents); if (is_array($PAGE_CACHE_LANG_LOADED)) { $PAGE_CACHE_LAZY_LOAD=true; $LANGUAGE=$PAGE_CACHE_LANG_LOADED; } } $PAGE_CACHE_FILE=$cache_path; } } require_lang('critical_error'); require_lang('global'); global $SEARCH__CONTENT_BITS; $SEARCH__CONTENT_BITS=NULL; if (strtolower(get_charset())=='utf-8') { global $HTML_ESCAPE_1_STRREP,$HTML_ESCAPE_2; $HTML_ESCAPE_1_STRREP=array('&'/*,'ì','î'*/,'"','\'','<','>'/*,'£'*/); $HTML_ESCAPE_2=array('&'/*,'"','"'*/,'"',''','<','>'/*,'£'*/); } global $OPTIONS; if (isset($OPTIONS)) { if (user_lang()!=get_site_default_lang()) { foreach ($OPTIONS as $name=>$option) { unset($OPTIONS[$name]['config_value_translated']); } } } } // ==== // CODE // ==== /** * Open up our language cache file for appending. */ function open_page_cache_file() { if ($GLOBALS['MEM_CACHE']===NULL) { global $PAGE_CACHE_FILE,$PAGE_CACHE_LAZY_LOAD; if ($PAGE_CACHE_FILE===NULL) return; if (!is_string($PAGE_CACHE_FILE)) return; $cache_path=$PAGE_CACHE_FILE; $PAGE_CACHE_FILE=@fopen($cache_path,'at'); if ($PAGE_CACHE_FILE!==false) { if (!$PAGE_CACHE_LAZY_LOAD) { require_code('files'); fix_permissions($cache_path,0666); } } else { $PAGE_CACHE_FILE=NULL; } } } /** * This function is called when no other language works, and it will return the original default language - 'EN'. You may change this to another language, but this is not advised, as ocPortal is being shipped with the EN language complete and unabridged as standard - hence you cannot go wrong if you leave it as EN. * In theory, this is the only hook to English that there is. * * @return LANGUAGE_NAME The fallback language */ function fallback_lang() { return 'EN'; } /** * Get the user's currently selected language. * * @return LANGUAGE_NAME The user's current language */ function user_lang() { global $USER_LANG_CACHED; if ($USER_LANG_CACHED!==NULL) return $USER_LANG_CACHED; global $MEMBER_CACHED,$USER_LANG_LOOP,$IN_MINIKERNEL_VERSION; if ($IN_MINIKERNEL_VERSION==1) { return get_site_default_lang(); } // In URL? $lang=''; $special_page_type=get_param('special_page_type',''); if ($special_page_type!='' && substr($special_page_type,0,5)=='lang_') { if (substr($special_page_type,0,13)=='lang_content_') { $lang=substr($special_page_type,13); } else { $lang=substr($special_page_type,5); } } if ($lang=='') { $lang=filter_naughty(either_param('lang',get_param('keep_lang',''))); } if ((!function_exists('get_member')) || ($USER_LANG_LOOP==1) || ($MEMBER_CACHED===NULL)) { global $USER_LANG_EARLY_CACHED; if ($USER_LANG_EARLY_CACHED!==NULL) return $USER_LANG_EARLY_CACHED; if (($lang!='') && (does_lang_exist($lang))) return $lang; if ((array_key_exists('GET_OPTION_LOOP',$GLOBALS)) && ($GLOBALS['GET_OPTION_LOOP']==0) && (function_exists('get_option')) && (get_option('detect_lang_browser',true)=='1')) { // In browser? $lang=get_lang_browser(); if ($lang!==NULL) { $USER_LANG_EARLY_CACHED=$lang; return $lang; } } $lang=get_site_default_lang(); $USER_LANG_EARLY_CACHED=$lang; return $lang; // Booting up and we don't know the user yet } $USER_LANG_LOOP=1; // In URL? if (($lang!='') && (does_lang_exist($lang))) { $USER_LANG_CACHED=$lang; } else { if (((get_forum_type()=='ocf') || (get_option('detect_lang_forum',true)=='1') || (get_option('detect_lang_browser',true)=='1')) && ((!$GLOBALS['DEV_MODE']) || (get_site_default_lang()!='Gibb'))) { // In forum? if (($USER_LANG_CACHED===NULL) && (get_option('detect_lang_forum',true)=='1')) { $USER_LANG_CACHED=get_lang_forum_user(get_member()); } if (($USER_LANG_CACHED===NULL) && (get_option('detect_lang_browser',true)=='1')) { $USER_LANG_CACHED=get_lang_browser(); } } } if ($USER_LANG_CACHED===NULL) { $USER_LANG_CACHED=get_site_default_lang(); } $USER_LANG_LOOP=0; return $USER_LANG_CACHED; } /** * Get the closest fit language code to what the browser is requesting. * * @return ?LANGUAGE_NAME The closest-fit language to what the browser wants (NULL: browser doesn't ask) */ function get_lang_browser() { // In browser? if (array_key_exists('HTTP_ACCEPT_LANGUAGE',$_SERVER)) $http_lang=$_SERVER['HTTP_ACCEPT_LANGUAGE']; elseif (array_key_exists('HTTP_ACCEPT_LANGUAGE',$_ENV)) $http_lang=$_ENV['HTTP_ACCEPT_LANGUAGE']; else $http_lang=''; if (strlen($http_lang)>0) { $http_langs=explode(',',$http_lang); foreach ($http_langs as $lang) { // Clean up $lang=strtoupper(trim($lang)); $pos=strpos($lang,';'); if ($pos!==false) $lang=substr($lang,0,$pos); $pos=strpos($lang,'-'); if ($pos!==false) $lang=substr($lang,0,$pos); if (does_lang_exist($lang)) { return $lang; } } } return NULL; } /** * Find whether the specified language exists. * * @param LANGUAGE_NAME The language * @return boolean Whether the language exists */ function does_lang_exist($lang) { if ($lang=='') return false; if ($lang=='Gibb') return true; // Test language if ($lang=='xxx') return true; // Test language $file_a=get_file_base().'/lang/'.$lang; $file_b=get_custom_file_base().'/lang_custom/'.$lang; $file_c=get_file_base().'/lang_custom/'.$lang; return is_dir($file_a) || is_dir($file_b) || is_dir($file_c); } /** * Get the site's default language, with support for URL overrides. * * @return LANGUAGE_NAME The site's default language */ function get_site_default_lang() { // Site default then global $SITE_INFO; if (!array_key_exists('default_lang',$SITE_INFO)) // We must be installing { global $IN_MINIKERNEL_VERSION; if ($IN_MINIKERNEL_VERSION==1) { if (array_key_exists('lang',$_POST)) return $_POST['lang']; if (array_key_exists('lang',$_GET)) return $_GET['lang']; } return fallback_lang(); } return $SITE_INFO['default_lang']; } /** * Get what language the given member uses. The language is sent through a mapping to ensure it is in the right format, or dumped if it will not map. * * @param MEMBER The member id * @return ?LANGUAGE_NAME The language used by the member (NULL: the language will not map) */ function get_lang_forum_user($member) { // In forum? $lang=$GLOBALS['FORUM_DRIVER']->forum_get_lang($member); if ((!is_null($lang)) && (strlen($lang)>0)) { $_lang=strtoupper($lang); if ((!is_dir(get_file_base().'/lang/'.$_lang)) && (!is_dir(get_custom_file_base().'/lang_custom/'.$_lang)) && (!is_dir(get_file_base().'/lang_custom/'.$_lang))) { $map_file_a=get_file_base().'/lang/map.ini'; $map_file_b=get_custom_file_base().'/lang_custom/map.ini'; if (!is_file($map_file_b)) $map_file_b=$map_file_a; $map=better_parse_ini_file($map_file_b); if (!array_key_exists($lang,$map)) { //fatal_exit('The specified language ('.$lang.') is missing. The language needs installing/creating in ocPortal, or the language map file needs updating (to map this language to a known ocPortal one), or both.'); $_lang=NULL; // Instead of the above, let's just fallback to default! So people's weird forum integration doesn't make ocPortal die } else { $_lang=$map[$lang]; if ((!is_dir(get_file_base().'/lang/'.$_lang)) && (!is_dir(get_custom_file_base().'/lang_custom/'.$_lang)) && (!is_dir(get_file_base().'/lang_custom/'.$_lang))) $_lang=NULL; } } if (!is_null($_lang)) return $_lang; } return NULL; } /** * Get the current language. * First it tries to get the GET or POST language values, then it tries the user's language, then site default, then it resorts to EN. * * @param ?MEMBER The member id (NULL: site default language, although better just to call get_site_default_lang directly) * @return LANGUAGE_NAME The current language */ function get_lang($member=NULL) { if ($member!==NULL) { if ($member==get_member()) return user_lang(); $lang=get_lang_forum_user($member); if ($lang!==NULL) return $lang; } return get_site_default_lang(); } /** * Includes a language file for use in the script. * If $type is not null, then this specifies whether to use 'lang_custom' or 'custom' (otherwise, normal priorities occur). * * @param ID_TEXT The language file name * @param ?LANGUAGE_NAME The language (NULL: uses the current language) * @param ?string The language type (lang_custom, or custom) (NULL: normal priorities are used) * @set lang_custom custom * @param boolean Whether to just return if there was a loading error */ function require_lang($codename,$lang=NULL,$type=NULL,$ignore_errors=false) // $type is for efficiency only - to avoid needing to doubly-search when requiring all { // So we can keep track of what code loads what langs global $LANGS_REQUESTED,$LANG_REQUESTED_LANG,$REQUIRE_LANG_LOOP,$PAGE_CACHE_LAZY_LOAD,$PAGE_CACHE_LANGS_REQUESTED,$LANG_LOADED_LANG,$LANGUAGE; $LANGS_REQUESTED[$codename]=1; if ($lang===NULL) $lang=user_lang(); if ((isset($LANG_REQUESTED_LANG[$lang])) && (isset($LANG_REQUESTED_LANG[$lang][$codename]))) return; $LANG_REQUESTED_LANG[$lang][$codename]=1; $cfb=get_custom_file_base(); $fb=get_file_base(); $codename=filter_naughty($codename); if ($PAGE_CACHE_LAZY_LOAD) { global $SITE_INFO; $support_smart_decaching=(!isset($SITE_INFO['disable_smart_decaching'])) || ($SITE_INFO['disable_smart_decaching']=='0'); if ($support_smart_decaching) { $cache_path=$cfb.'/lang_cached/'.$lang.'/'.$codename.'.lcd'; $lang_file_default=$fb.'/lang/'.$lang.'/'.$codename.'.ini'; if (!is_file($lang_file_default)) { $lang_file_default=$fb.'/lang/'.fallback_lang().'/'.$codename.'.ini'; } $lang_file=$fb.'/lang_custom/'.$lang.'/'.$codename.'.ini'; if (!is_file($lang_file)) { $lang_file=$fb.'/lang_custom/'.$lang.'/'.$codename.'.po'; if (!is_file($lang_file)) { $lang_file=$fb.'/lang_custom/'.$lang.'/'.filter_naughty($codename).'-'.strtolower($lang).'.po'; if (!is_file($lang_file)) { $lang_file=$lang_file_default; } else { if (!is_file($lang_file_default)) $lang_file_default=$lang_file; } } else { if (!is_file($lang_file_default)) $lang_file_default=$lang_file; } } else { if (!is_file($lang_file_default)) $lang_file_default=$lang_file; } } if ((!$support_smart_decaching) || ((is_file($cache_path)) && (is_file($lang_file)) && (@/*race conditions*/filemtime($cache_path)>filemtime($lang_file)) && (@/*race conditions*/filemtime($cache_path)>filemtime($lang_file_default)))) { if ($lang===NULL) $lang=user_lang(); $PAGE_CACHE_LANGS_REQUESTED[]=array($codename,$lang); return; } else // Invalidate it, as our .lcd cache was dirty { global $PAGE_CACHE_FILE; open_page_cache_file(); $LANGUAGE=array(); @rewind($PAGE_CACHE_FILE); @ftruncate($PAGE_CACHE_FILE,0); $PAGE_CACHE_LAZY_LOAD=false; $LANG_LOADED_LANG=array(); $PAGE_CACHE_LANGS_REQUESTED[]=array($codename,$lang); foreach ($PAGE_CACHE_LANGS_REQUESTED as $request) { list($that_codename,$that_lang)=$request; unset($LANG_REQUESTED_LANG[$that_lang][$that_codename]); require_lang($that_codename,$that_lang,NULL,$ignore_errors); } } } if ((isset($LANG_LOADED_LANG[$lang])) && (isset($LANG_LOADED_LANG[$lang][$codename]))) return; $REQUIRE_LANG_LOOP++; if ((function_exists('memory_get_usage')) && (isset($_GET['keep_show_loading'])) && ($_GET['keep_show_loading']=='1')) { print('<!-- require_lang: '.htmlentities($codename).' ('.integer_format(memory_get_usage()).' before) -->'."\n"); flush(); } $bad=false; $done=false; if (!isset($LANGUAGE[$lang])) $LANGUAGE[$lang]=array(); $cache_path=$cfb.'/lang_cached/'.$lang.'/'.$codename.'.lcd'; // Try lang_cached if ($GLOBALS['MEM_CACHE']!==NULL) { $desire_cache=true; global $SITE_INFO; $support_smart_decaching=(!isset($SITE_INFO['disable_smart_decaching'])) || ($SITE_INFO['disable_smart_decaching']=='0'); if ($support_smart_decaching) { $lang_file=$fb.'/lang/'.$lang.'/'.$codename.'.ini'; if (!is_file($lang_file)) { $lang_file=$fb.'/lang/'.$lang.'/'.$codename.'.po'; if (!is_file($lang_file)) $lang_file=$fb.'/lang/'.$lang.'/'.filter_naughty($codename).'-'.strtolower($lang).'.po'; } $pcache=persistent_cache_get(array('LANG',$lang,$codename),is_file($lang_file)?filemtime($lang_file):NULL); } else { $pcache=persistent_cache_get(array('LANG',$lang,$codename)); } if (is_array($pcache)) { $LANGUAGE[$lang]+=$pcache; $done=true; } } else { $desire_cache=(function_exists('get_option')) && ((get_option('is_on_lang_cache',true)=='1') || (get_param_integer('keep_cache',0)==1) || (get_param_integer('cache',0)==1)) && (get_param_integer('keep_cache',NULL)!==0) && (get_param_integer('cache',NULL)!==0); if ($desire_cache) { $cache_path=$cfb.'/lang_cached/'.$lang.'/'.$codename.'.lcd'; $lang_file_default=$fb.'/lang/'.$lang.'/'.$codename.'.ini'; if (!is_file($lang_file_default)) { $lang_file_default=$fb.'/lang/'.fallback_lang().'/'.$codename.'.ini'; } $lang_file=$fb.'/lang_custom/'.$lang.'/'.$codename.'.ini'; if (!is_file($lang_file)) { $lang_file=$fb.'/lang_custom/'.$lang.'/'.$codename.'.po'; if (!is_file($lang_file)) { $lang_file=$fb.'/lang_custom/'.$lang.'/'.filter_naughty($codename).'-'.strtolower($lang).'.po'; if (!is_file($lang_file)) { $lang_file=$lang_file_default; } } } if (!is_file($lang_file_default)) $lang_file_default=$lang_file; if ((is_file($cache_path)) && ((!is_file($lang_file)) || ((@/*race conditions*/filemtime($cache_path)>filemtime($lang_file)) && (@/*race conditions*/filemtime($cache_path)>filemtime($lang_file_default))))) { $tmp=@file_get_contents($cache_path); if ($tmp!='') { $unserialized=@unserialize($tmp); if ($unserialized!==false) { $LANGUAGE[$lang]+=$unserialized; $done=true; } } } } } if (!$done) { if (($desire_cache) && (is_file($cache_path))) // Must have been dirty cache, so we need to kill compiled templates too (as lang is compiled into them) { require_code('view_modes'); global $ERASED_TEMPLATES_ONCE; if (!$ERASED_TEMPLATES_ONCE) erase_cached_templates(); } require_code('lang_compile'); $bad=$bad || require_lang_compile($codename,$lang,$type,$cache_path,$ignore_errors); } global $LANG_LOADED; $LANG_LOADED[$codename]=$type; if (!isset($LANG_LOADED_LANG[$lang])) $LANG_LOADED_LANG[$lang]=array(); $LANG_LOADED_LANG[$lang][$codename]=1; } /** * Include all the language files for use in the script. * NOTE: This may reduce performance, so you should only use it if you really have to. * * @param ?LANGUAGE_NAME The language to include files from (NULL: use current users language). * @param boolean Only load it up if it is specifically defined for our language. */ function require_all_lang($lang=NULL,$only_if_for_lang=false) { if (is_null($lang)) { global $REQUIRED_ALL_LANG; if (array_key_exists($lang,$REQUIRED_ALL_LANG)) return; $REQUIRED_ALL_LANG[$lang]=true; } if (is_null($lang)) $lang=user_lang(); require_code('lang2'); $lang_files=get_lang_files(fallback_lang()); foreach (array_keys($lang_files) as $file) { if ((!$only_if_for_lang) || (is_file(get_custom_file_base().'/lang_custom/'.$lang.'/'.$file.'.ini')) || (is_file(get_custom_file_base().'/lang/'.$lang.'/'.$file.'.ini')) || (is_file(get_custom_file_base().'/lang_custom/'.$lang.'/'.$file.'.po')) || (is_file(get_custom_file_base().'/lang_custom/'.$lang.'/'.$file.'-'.strtolower($lang).'.po'))) require_lang($file,$lang,NULL,true); } } /** * Convert the specified language codename to the default content, and return the language key. * * @param ID_TEXT The language codename * @param boolean Whether the given codes value is to be parsed as comcode * @param integer The level of importance this language string holds * @return integer The language ID */ function lang_code_to_default_content($code,$comcode=false,$level=2) { $lang_key=insert_lang(do_lang($code),$level,NULL,$comcode); $langs=find_all_langs(); foreach ($langs as $lang=>$lang_type) { if ($lang!=user_lang()) { if (is_file(get_file_base().'/'.$lang_type.'/'.$lang.'/critical_error.ini')) // Make sure it's a reasonable looking pack, not just a stub (Google Translate addon can be made to go nuts otherwise) insert_lang(do_lang($code,'','','',$lang),$level,NULL,true,$lang_key,$lang); } } return $lang_key; } /** * Require all the open language files. This doesn't hurt performance a lot. * * @param ?LANGUAGE_NAME The language to require open files from (NULL: uses the current language) */ function require_all_open_lang_files($lang=NULL) { global $PAGE_CACHE_LAZY_LOAD,$LANG_REQUESTED_LANG,$LANGS_REQUESTED; $PAGE_CACHE_LAZY_LOAD=false; $LANG_REQUESTED_LANG=array(); // So require_lang will do a re-load $langs_requested_copy=$LANGS_REQUESTED; foreach (array_keys($langs_requested_copy) as $toload) { require_lang($toload,$lang,NULL,true); } // Block cacheing might have hidden that we loaded these require_lang('global',$lang,NULL,true); require_lang('critical_error',$lang,NULL,true); } /** * URL'ise specially encoded text-acceptance language strings. * * @param string The language string * @param mixed The URL (either tempcode or string) * @param string The title of the hyperlink * @param boolean Whether to use a new window * @return tempcode The encoded version */ function urlise_lang($string,$url,$title='',$new_window=false) { require_code('lang_urlise'); return _urlise_lang($string,$url,$title,$new_window); } /** * Stop some text being escapable by the Tempcode layer. * * @param mixed Text * @return tempcode Text that can't be escaped */ function protect_from_escaping($in) { return do_lang_tempcode('dont_escape_trick',$in); } /** * Get the human-readable form of a language id, or a language entry from a language INI file. * * @param ID_TEXT The language id * @param ?mixed The first token [string or tempcode] (replaces {1}) (NULL: none) * @param ?mixed The second token [string or tempcode] (replaces {2}) (NULL: none) * @param ?mixed The third token (replaces {3}). May be an array of [of string], to allow any number of additional args (NULL: none) * @param ?LANGUAGE_NAME The language to use (NULL: users language) * @param boolean Whether to cause ocPortal to exit if the lookup does not succeed * @return ?mixed The human-readable content (NULL: not found). String normally. Tempcode if tempcode parameters. */ function _do_lang($codename,$token1=NULL,$token2=NULL,$token3=NULL,$lang=NULL,$require_result=true) { global $LANGUAGE,$USER_LANG_CACHED,$RECORD_LANG_STRINGS,$XSS_DETECT,$PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED; if ($lang===NULL) { $lang=($USER_LANG_CACHED===NULL)?user_lang():$USER_LANG_CACHED; }// else // This else assumes we initially load all language files in the users language. Reasonable. EDIT: Actually, no it is not - the user_lang() initially is not accurate until ocPortal gets past a certain startup position { if ($GLOBALS['SEMI_DEV_MODE']) // Special syntax for easily inlining language strings { $pos=strpos($codename,'='); if ($pos!==false) { // Find loaded file with smallest levenstein distance to current page $best=mixed(); $best_for=NULL; global $LANGS_REQUESTED; foreach (array_keys($LANGS_REQUESTED) as $possible) { $dist=levenshtein(get_page_name(),$possible); if ((is_null($best)) || ($best>$dist)) { $best=$dist; $best_for=$possible; } } $save_path=get_file_base().'/lang/'.fallback_lang().'/'.$best_for.'.ini'; if (!is_file($save_path)) $save_path=get_file_base().'/lang_custom/'.fallback_lang().'/'.$best_for.'.ini'; // Tack language strings onto this file list($codename,$value)=explode('=',$codename,2); $myfile=fopen($save_path,'at'); fwrite($myfile,"\n".$codename.'='.$value); fclose($myfile); // Fake-load the string $LANGUAGE[$lang][$codename]=$value; // Go through all required files, doing a string replace if needed $included_files=get_included_files(); foreach ($included_files as $inc) { $orig_contents=file_get_contents($inc); $contents=str_replace("'".$codename.'='.$value."'","'".$codename."'",$orig_contents); if ($orig_contents!=$contents) { $myfile=fopen($inc,'wt'); fwrite($myfile,$contents); fclose($myfile); } } } } $there=isset($LANGUAGE[$lang][$codename]); if (!$there) { $pos=strpos($codename,':'); if ($pos!==false) { require_lang(substr($codename,0,$pos),NULL,NULL,!$require_result); $codename=substr($codename,$pos+1); } $there=isset($LANGUAGE[$lang][$codename]); } if ($RECORD_LANG_STRINGS) { global $RECORDED_LANG_STRINGS; $RECORDED_LANG_STRINGS[$codename]=1; } if ((!$there) && ((!isset($LANGUAGE[$lang])) || (!array_key_exists($codename,$LANGUAGE[$lang])))) { global $PAGE_CACHE_LAZY_LOAD,$PAGE_CACHE_LANGS_REQUESTED,$LANG_REQUESTED_LANG; if ($PAGE_CACHE_LAZY_LOAD) { $PAGE_CACHE_LAZY_LOAD=false; // We can't be lazy any more, but we will keep growing our pool so hopefully CAN be lazy the next time foreach ($PAGE_CACHE_LANGS_REQUESTED as $request) { list($that_codename,$that_lang)=$request; unset($LANG_REQUESTED_LANG[$that_lang][$that_codename]); require_lang($that_codename,$that_lang,NULL,!$require_result); } $ret=_do_lang($codename,$token1,$token2,$token3,$lang,$require_result); if ($ret===NULL) { $PAGE_CACHE_LANG_LOADED[$lang][$codename]=NULL; if ($GLOBALS['MEM_CACHE']!==NULL) { persistent_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED); } else { open_page_cache_file(); @rewind($PAGE_CACHE_FILE); @ftruncate($PAGE_CACHE_FILE,0); @fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED)); } } return $ret; } require_all_open_lang_files($lang); } } if ($lang=='xxx') return 'xxx'; // Helpful for testing language compliancy. We don't expect to see non x's if we're running this language if ((!isset($LANGUAGE[$lang][$codename])) && (($require_result) || (!isset($LANGUAGE[$lang])) || (!array_key_exists($codename,$LANGUAGE[$lang])))) { if ($lang!=fallback_lang()) { $ret=do_lang($codename,$token1,$token2,$token3,fallback_lang(),$require_result); if ($PAGE_CACHE_FILE!==NULL) { if ((!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename])) && (isset($PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename]))) { $PAGE_CACHE_LANG_LOADED[$lang][$codename]=$PAGE_CACHE_LANG_LOADED[fallback_lang()][$codename]; // Will have been cached into fallback_lang() from the nested do_lang call, we need to copy it into our cache bucket for this language if ($GLOBALS['MEM_CACHE']!==NULL) { persistent_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED); } else { open_page_cache_file(); @rewind($PAGE_CACHE_FILE); @ftruncate($PAGE_CACHE_FILE,0); @fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED)); } } } return $ret; } else { if ($require_result) { global $USER_LANG_LOOP,$REQUIRE_LANG_LOOP; //print_r(debug_backtrace()); if ($USER_LANG_LOOP==1) critical_error('RELAY','Missing language code: '.escape_html($codename).'. This language code is required to produce error messages, and thus a critical error was prompted by the non-ability to show less-critical error messages. It is likely the source language files (lang/'.fallback_lang().'/*.ini) for ocPortal on this website have been corrupted.'); if ($REQUIRE_LANG_LOOP>=2) return ''; // Probably failing to load global.ini, so just output with some text missing require_code('view_modes'); erase_cached_language(); fatal_exit(do_lang_tempcode('MISSING_LANG_ENTRY',escape_html($codename))); } else { return NULL; } } } if ($PAGE_CACHE_FILE!==NULL) { if ((!isset($PAGE_CACHE_LANG_LOADED[$lang][$codename])) && ((!isset($PAGE_CACHE_LANG_LOADED[$lang])) || (!array_key_exists($codename,$PAGE_CACHE_LANG_LOADED[$lang])))) { $PAGE_CACHE_LANG_LOADED[$lang][$codename]=$LANGUAGE[$lang][$codename]; if ($GLOBALS['MEM_CACHE']!==NULL) { persistent_cache_set($PAGE_CACHE_FILE,$PAGE_CACHE_LANG_LOADED); } else { open_page_cache_file(); @rewind($PAGE_CACHE_FILE); @ftruncate($PAGE_CACHE_FILE,0); @fwrite($PAGE_CACHE_FILE,serialize($PAGE_CACHE_LANG_LOADED)); } } } // Put in parameters static $non_plural_non_vowel=array('1','b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z'); $looked_up=$LANGUAGE[$lang][$codename]; if ($looked_up===NULL) { return NULL; // Learning cache pool has told us this string definitely does not exist } $out=str_replace('\n',"\n",$looked_up); $plural_or_vowel_check=strpos($out,'|')!==false; if ($XSS_DETECT) ocp_mark_as_escaped($out); if ($token1!==NULL) { if (((is_object($token1)) && ($token2===NULL)) || (($token2!==NULL) && (is_object($token2)))) // Tempcode only supported in first two { $bits=preg_split('#\{\d[^\}]*\}#',$out,2,PREG_SPLIT_OFFSET_CAPTURE); $ret=new ocp_tempcode(); foreach ($bits as $bit) { if ($XSS_DETECT) ocp_mark_as_escaped($bit[0]); $at=$bit[1]; if ($at!=0) { if ($out[$at-2]=='1') $ret->attach($token1); elseif ($out[$at-2]=='2') $ret->attach($token2); elseif (($plural_or_vowel_check) && (substr($out[$at-2],0,2)=='1|')) { $exploded=explode('|',$out[$at-2]); $_token=$token1->evaluate(); $_token_denum=str_replace(',','',$_token); $ret->attach((in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($_token,0,1)),$non_plural_non_vowel))?$exploded[1]:$exploded[2]); } elseif (($plural_or_vowel_check) && (substr($out[$at-2],0,2)=='2|')) { $exploded=explode('|',$out[$at-2]); $_token=$token2->evaluate(); $_token_denum=str_replace(',','',$_token); $ret->attach((in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($_token,0,1)),$non_plural_non_vowel))?$exploded[1]:$exploded[2]); } } $ret->attach($bit[0]); } return $ret; } elseif ($token1!==NULL) { $out=str_replace('{1}',$token1,$out); if ($plural_or_vowel_check) { $_token_denum=str_replace(',','',$token1); $out=preg_replace('#\{1\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token1,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out); } if (($XSS_DETECT) && (ocp_is_escaped($token1))) ocp_mark_as_escaped($out); } if ($token2!==NULL) { if ($XSS_DETECT) $escaped=ocp_is_escaped($out); $out=str_replace('{2}',$token2,$out); if ($plural_or_vowel_check) { $_token_denum=str_replace(',','',$token1); $out=preg_replace('#\{2\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token2,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out); } if (($XSS_DETECT) && (ocp_is_escaped($token2)) && ($escaped)) ocp_mark_as_escaped($out); if ($token3!==NULL) { $i=3; if (!is_array($token3)) $token3=array($token3); foreach ($token3 as $token) { if ($XSS_DETECT) $escaped=ocp_is_escaped($out); $out=str_replace('{'.strval($i).'}',$token,$out); if ($plural_or_vowel_check) { $_token_denum=str_replace(',','',$token); $out=preg_replace('#\{'.strval($i).'\|(.*)\|(.*)\}#U',(in_array(is_numeric($_token_denum)?$_token_denum:strtolower(substr($token,0,1)),$non_plural_non_vowel))?'\\1':'\\2',$out); } if (($XSS_DETECT) && (ocp_is_escaped($token)) && ($escaped)) ocp_mark_as_escaped($out); $i++; } } } } return $out; } /** * Get an array of all the installed languages that can be found in root/lang/ and root/lang_custom/ * * @param boolean Whether to even find empty languages * @return array The installed languages (map, lang=>type) */ function find_all_langs($even_empty_langs=false) { require_code('lang3'); return _find_all_langs($even_empty_langs); } /** * Get a nice formatted XHTML listed language selector. * * @param ?LANGUAGE_NAME The language to have selected by default (NULL: uses the current language) * @param boolean Whether to show languages that have no language details currently defined for them * @return tempcode The language selector */ function nice_get_langs($select_lang=NULL,$show_unset=false) { require_code('lang3'); return _nice_get_langs($select_lang,$show_unset); } // ======= // CONTENT // ======= /** * Insert a comcode language entry into the translation table, and returns the id. * * @param string The text * @param integer The level of importance this language string holds * @set 1 2 3 4 * @param ?object The database connection to use (NULL: standard site connection) * @param boolean Whether to insert it as an admin (any comcode parsing will be carried out with admin privileges) * @param ?string The special identifier for this lang code on the page it will be displayed on; this is used to provide an explicit binding between languaged elements and greater templated areas (NULL: none) * @param integer Comcode parser wrap position * @param boolean Whether to generate a fatal error if there is invalid Comcode * @param boolean Whether we are saving as a 'volatile' file extension (used in the XML DB driver, to mark things as being non-syndicated to subversion) * @return integer The id of the newly added language entry */ function insert_lang_comcode($text,$level,$connection=NULL,$insert_as_admin=false,$pass_id=NULL,$wrap_pos=60,$preparse_mode=true,$save_as_volatile=false) { if (is_null($connection)) $connection=$GLOBALS['SITE_DB']; return insert_lang($text,$level,$connection,true,NULL,NULL,$insert_as_admin,$pass_id,NULL,$wrap_pos,$preparse_mode,$save_as_volatile); } /** * Insert a language entry into the translation table, and returns the id. * * @param string The text * @param integer The level of importance this language string holds * @set 1 2 3 4 * @param ?object The database connection to use (NULL: standard site connection) * @param boolean Whether it is to be parsed as comcode * @param ?integer The id to use for the language entry (NULL: work out next available) * @param ?LANGUAGE_NAME The language (NULL: uses the current language) * @param boolean Whether to insert it as an admin (any comcode parsing will be carried out with admin privileges) * @param ?string The special identifier for this lang code on the page it will be displayed on; this is used to provide an explicit binding between languaged elements and greater templated areas (NULL: none) * @param ?string Assembled Tempcode portion (NULL: work it out) * @param integer Comcode parser wrap position * @param boolean Whether to generate a fatal error if there is invalid Comcode * @param boolean Whether we are saving as a 'volatile' file extension (used in the XML DB driver, to mark things as being non-syndicated to subversion) * @return integer The id of the newly added language entry */ function insert_lang($text,$level,$connection=NULL,$comcode=false,$id=NULL,$lang=NULL,$insert_as_admin=false,$pass_id=NULL,$text2=NULL,$wrap_pos=60,$preparse_mode=true,$save_as_volatile=false) { require_code('lang3'); return _insert_lang($text,$level,$connection,$comcode,$id,$lang,$insert_as_admin,$pass_id,$text2,$wrap_pos,$preparse_mode,$save_as_volatile); } /** * Remap the specified comcode language id, and return the id again - the id isn't changed. * * @param integer The language entries id * @param string The text to remap to * @param ?object The database connection to use (NULL: standard site connection) * @param ?string The special identifier for this lang code on the page it will be displayed on; this is used to provide an explicit binding between languaged elements and greater templated areas (NULL: none) * @param ?MEMBER The member performing the change (NULL: current member) * @param boolean Whether to generate Comcode as arbitrary admin * @return integer The language entries id */ function lang_remap_comcode($id,$text,$connection=NULL,$pass_id=NULL,$source_member=NULL,$as_admin=false) { if (is_null($connection)) $connection=$GLOBALS['SITE_DB']; return lang_remap($id,$text,$connection,true,$pass_id,$source_member,$as_admin); } /** * Remap the specified language id, and return the id again - the id isn't changed. * * @param integer The language entries id * @param string The text to remap to * @param ?object The database connection to use (NULL: standard site connection) * @param boolean Whether it is to be parsed as comcode * @param ?string The special identifier for this lang code on the page it will be displayed on; this is used to provide an explicit binding between languaged elements and greater templated areas (NULL: none) * @param ?MEMBER The member performing the change (NULL: current member) * @param boolean Whether to generate Comcode as arbitrary admin * @param boolean Whether to backup the language string before changing it * @return integer The language entries id */ function lang_remap($id,$text,$connection=NULL,$comcode=false,$pass_id=NULL,$source_member=NULL,$as_admin=false,$backup_string=false) { require_code('lang3'); return _lang_remap($id,$text,$connection,$comcode,$pass_id,$source_member,$as_admin,$backup_string); } /** * Delete the specified language entry from the translation table. * * @param integer The id * @param ?object The database connection to use (NULL: standard site connection) */ function delete_lang($id,$connection=NULL) { if (is_null($connection)) $connection=$GLOBALS['SITE_DB']; $connection->query_delete('translate',array('id'=>$id)); } /** * This function is an offshoot of get_translated_text, it instead returns parsed comcode that is linked to the specified language id. * * @param integer The id * @param ?object The database connection to use (NULL: standard site connection) * @param ?LANGUAGE_NAME The language (NULL: uses the current language) * @param boolean Whether to force it to the specified language * @param boolean Whether to force as_admin, even if the lang string isn't stored against an admin (designed for comcode page cacheing) * @param boolean Whether to remove from the Tempcode cache when we're done, for performance reasons (normally don't bother with this, but some code knows it won't be needed again -- esp Comcode cache layer -- and saves RAM by removing it) * @return ?tempcode The parsed comcode (NULL: the text couldn't be looked up) */ function get_translated_tempcode($entry,$connection=NULL,$lang=NULL,$force=false,$as_admin=false,$clear_away_from_cache=false) { if ($entry==0) return paragraph(do_lang_tempcode('FAILED_ENTRY'),'rtgtedgrgd'); if ($connection===NULL) $connection=$GLOBALS['SITE_DB']; global $RECORD_LANG_STRINGS_CONTENT; if ($RECORD_LANG_STRINGS_CONTENT) { global $RECORDED_LANG_STRINGS_CONTENT; $RECORDED_LANG_STRINGS_CONTENT[$entry]=($connection->connection_write!=$GLOBALS['SITE_DB']->connection_write); } if ($lang===NULL) $lang=user_lang(); if ($lang=='xxx') return make_string_tempcode('!!!'); // Helpful for testing language compliancy. We don't expect to see non x's/!'s if we're running this language if ((isset($connection->text_lookup_cache[$entry])) && ($lang==user_lang())) { $ret=$connection->text_lookup_cache[$entry]; if ($ret!=='') { if (is_string($ret)) { $connection->text_lookup_cache[$entry]=new ocp_tempcode(); $connection->text_lookup_cache[$entry]->from_assembly($ret); $ret=$connection->text_lookup_cache[$entry]; } if ($clear_away_from_cache) { unset($connection->text_lookup_cache[$entry]); unset($connection->text_lookup_original_cache[$entry]); } return $ret; } } global $SEARCH__CONTENT_BITS; if ($SEARCH__CONTENT_BITS!==NULL) // Doing a search so we need to reparse, with highlighting on { $_result=$connection->query_select('translate',array('text_original','source_user'),array('id'=>$entry,'language'=>$lang),'',1); if (array_key_exists(0,$_result)) { global $LAX_COMCODE; $temp=$LAX_COMCODE; $LAX_COMCODE=true; $result=$_result[0]; $ret=comcode_to_tempcode($result['text_original'],$result['source_user'],$as_admin,60,NULL,$connection,false,false,false,false,false,$SEARCH__CONTENT_BITS); $LAX_COMCODE=$temp; return $ret; } } $_result=$connection->query_select('translate',array('text_parsed','text_original'),array('id'=>$entry,'language'=>$lang),'',1); $result=isset($_result[0])?$_result[0]['text_parsed']:NULL; if (isset($_result[0])) { if ($lang==user_lang()) { $connection->text_lookup_original_cache[$entry]=$_result[0]['text_original']; } } if (($result===NULL) || ($result=='') || (is_browser_decacheing())) // Not cached { require_code('lang3'); return parse_translated_text($entry,$connection,$lang,$force,$as_admin); } $parsed=new ocp_tempcode(); if (!$parsed->from_assembly($result,true)) { require_code('lang3'); return parse_translated_text($entry,$connection,$lang,$force,$as_admin); } if ($lang==user_lang()) { $connection->text_lookup_cache[$entry]=$parsed; } return $parsed; } /** * Try to return the human-readable version of the language id, passed in as $entry. * * @param integer The id * @param ?object The database connection to use (NULL: standard site connection) * @param ?LANGUAGE_NAME The language (NULL: uses the current language) * @param boolean Whether to force it to the specified language * @return ?string The human-readable version (NULL: could not look up when $force was on) */ function get_translated_text($entry,$connection=NULL,$lang=NULL,$force=false) { if ($entry==0) return do_lang('FAILED_ENTRY'); if ($entry===NULL) fatal_exit(do_lang_tempcode('NULL_LANG_STRING')); if ($connection===NULL) $connection=$GLOBALS['SITE_DB']; global $RECORD_LANG_STRINGS_CONTENT; if ($RECORD_LANG_STRINGS_CONTENT) { global $RECORDED_LANG_STRINGS_CONTENT; $RECORDED_LANG_STRINGS_CONTENT[$entry]=($connection->connection_write!=$GLOBALS['SITE_DB']->connection_write); } if ($lang===NULL) $lang=user_lang(); if ((isset($connection->text_lookup_original_cache[$entry])) && ($lang==user_lang())) { return $connection->text_lookup_original_cache[$entry]; } if ($lang=='xxx') return '!!!'; // Helpful for testing language compliancy. We don't expect to see non x's/!'s if we're running this language $result=$connection->query_select('translate',array('text_original','text_parsed'),array('id'=>$entry,'language'=>$lang),'',1); if (!isset($result[0])) { if ($force) return NULL; $result=$connection->query_select('translate',array('*'),array('id'=>$entry),'',1); if (!isset($result[0])) { $result=$connection->query_select('translate',array('*'),array('id'=>$entry),'',1); } if (isset($result[0])) { $connection->query_insert('translate',array('broken'=>1,'language'=>$lang)+$result[0]); } } if (!isset($result[0])) { $member_id=function_exists('get_member')?get_member():$GLOBALS['FORUM_DRIVER']->get_guest_id(); $connection->query_insert('translate',array('id'=>$entry,'source_user'=>$member_id,'broken'=>0,'importance_level'=>3,'text_original'=>'','text_parsed'=>'','language'=>$lang)); $msg=do_lang('LANGUAGE_CORRUPTION',strval($entry)); if (preg_match('#^localhost[\.\:$]#',ocp_srv('HTTP_HOST'))!=0) fatal_exit($msg); require_code('site'); attach_message(make_string_tempcode($msg),'warn'); return ''; } if ($lang==user_lang()) { $connection->text_lookup_original_cache[$entry]=$result[0]['text_original']; $connection->text_lookup_cache[$entry]=$result[0]['text_parsed']; } return $result[0]['text_original']; } /** * Convert a language string that is Comcode to tempcode, with potential cacheing in the db. * * @param ID_TEXT The language string ID * @return tempcode The parsed Comcode */ function comcode_lang_string($lang_code) { require_code('lang3'); return _comcode_lang_string($lang_code); } /** * UI to choose a language. * * @param tempcode Title for the form * @param boolean Whether to give a tip about edit order * @param boolean Whether to add an 'all' entry to the list * @return mixed The UI (tempcode) or the language to use (string/LANGUAGE_NAME) */ function choose_language($title,$tip=false,$allow_all_selection=false) { if (!multi_lang()) return user_lang(); $lang=either_param('lang',/*get_param('keep_lang',NULL)*/NULL); if (!is_null($lang)) return filter_naughty($lang); if (!$tip) { $text=do_lang_tempcode('CHOOSE_LANG_DESCRIP'); } else { global $LANGS_MAP; if ($LANGS_MAP===NULL) { $map_a=get_file_base().'/lang/langs.ini'; $map_b=get_custom_file_base().'/lang_custom/langs.ini'; if (!is_file($map_b)) $map_b=$map_a; $LANGS_MAP=better_parse_ini_file($map_b); } $lang_name=get_site_default_lang(); if (array_key_exists($lang_name,$LANGS_MAP)) $lang_name=$LANGS_MAP[$lang_name]; $text=do_lang_tempcode('CHOOSE_LANG_DESCRIP_ADD_TO_MAIN_LANG_FIRST',escape_html($lang_name)); } $langs=new ocp_tempcode(); if ($allow_all_selection) { $langs->attach(form_input_list_entry('',false,do_lang_tempcode('_ALL'))); } $langs->attach(nice_get_langs()); require_code('form_templates'); $fields=form_input_list(do_lang_tempcode('LANGUAGE'),do_lang_tempcode('DESCRIPTION_LANGUAGE'),'lang',$langs,NULL,true); $hidden=build_keep_post_fields(); $url=get_self_url(); return do_template('FORM_SCREEN',array('_GUID'=>'1a2823d450237aa299c095bf9c689a2a','SKIP_VALIDATION'=>true,'HIDDEN'=>$hidden,'SUBMIT_NAME'=>do_lang_tempcode('PROCEED'),'TITLE'=>$title,'FIELDS'=>$fields,'URL'=>$url,'TEXT'=>$text)); }
© 2017 -
ZeroByte.ID
.